{"id":18302266,"url":"https://github.com/polyhedraldev/paralithic","last_synced_at":"2025-04-05T14:31:24.157Z","repository":{"id":45856067,"uuid":"335793024","full_name":"PolyhedralDev/Paralithic","owner":"PolyhedralDev","description":"Super fast expression evaluator/parser written in Java","archived":false,"fork":false,"pushed_at":"2024-10-24T05:55:04.000Z","size":333,"stargazers_count":23,"open_issues_count":2,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-10-24T11:59:11.323Z","etag":null,"topics":["expression-evaluator","expression-parser","hacktoberfest","java","objectweb-asm","performance"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PolyhedralDev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-04T00:26:58.000Z","updated_at":"2024-10-24T05:55:08.000Z","dependencies_parsed_at":"2024-10-28T01:28:14.929Z","dependency_job_id":null,"html_url":"https://github.com/PolyhedralDev/Paralithic","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PolyhedralDev%2FParalithic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PolyhedralDev%2FParalithic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PolyhedralDev%2FParalithic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PolyhedralDev%2FParalithic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PolyhedralDev","download_url":"https://codeload.github.com/PolyhedralDev/Paralithic/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247352610,"owners_count":20925301,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["expression-evaluator","expression-parser","hacktoberfest","java","objectweb-asm","performance"],"created_at":"2024-11-05T15:18:43.651Z","updated_at":"2025-04-05T14:31:24.143Z","avatar_url":"https://github.com/PolyhedralDev.png","language":"Java","readme":"# Paralithic\n\n[![Build Status](https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fci.solo-studios.ca%2Fjob%2FPolyhedralDev%2Fjob%2FParalithic%2Fjob%2Fmaster%2F\u0026style=for-the-badge\u0026link=https%3A%2F%2Fci.solo-studios.ca%2Fjob%2FPolyhedralDev%2Fjob%2FParalithic%2Fjob%2Fmaster%2F)](https://ci.solo-studios.ca/job/PolyhedralDev/job/Paralithic/job/master/)\n[![GitHub Tag](https://img.shields.io/github/v/tag/PolyhedralDev/Paralithic?sort=semver\u0026style=for-the-badge)](https://github.com/PolyhedralDev/Paralithic/tags)\n[![Chat](https://img.shields.io/discord/715448651786485780?style=for-the-badge\u0026color=7389D8)](https://terra.polydev.org/contact.html)\n\n\u003cbig\u003e\u003cb\u003eSuper fast expression evaluator/parser written in Java.\u003c/b\u003e\u003c/big\u003e\n\n## About\n\nParalithic is a library for parsing and evaluating mathematical expressions. It uses ASM to dynamically\ngenerate implementations of the `Expression` interface representing the expression, with expressions converted directly\ninto Java bytecode for maximum performance, and maximum room for JIT optimization. Paralithic also uses several AOT\noptimization techniques, such as:\n\n* Evaluating stateless functions with constant arguments at parse time, replacing them with constants.\n* Evaluating binary operations with constant operands at parse time, replacing them with constants.\n* Combining constants in nested commutative binary operations.\n\nBy directly generating bytecode to be executed by the JVM, and with the above optimizations, Paralithic expressions are\nable to achieve about the same speed as hard-coded ones.\n\nParalithic uses [Seismic](https://github.com/PolyhedralDev/Seismic) as it's backing math library, which provides many of\nthe math functions\nbuilt into Paralithic, and provides more optimized versions for many functions built into Java's Math class.\n\n## Usage\n\n```java\nParser parser = new Parser(); // Create parser instance.\nScope scope = new Scope(); // Create variable scope. This scope can hold both constants and invocation variables scope.\n\naddInvocationVariable(\"x\"); // Register variable to be used in calls to #evaluate. Values are passed in the order they are registered scope.\n\ncreate(\"y\",3); // Create named constant y with value 3\n\nExpression expression = parser.parse(\"x * 4 + pow(2, y)\", scope); // expression.\n\nevaluate(3); // 20 (3*4 + 2^3 = 20)\n```\n\n## Performance\n\nThe expression `(sin(x) + 2 + ((7-5) * (3.14159 * x^(14-10)) + sin(-3.141) + (0%x)) * x/3 * 3/sqrt(x))` was evaluated in\n3 different\nexpression libraries.\n\nThe test was run for 3 iterations of 1 second each to allow the JIT to warmup and optimize as much as possible,\nthe next 3 iterations of 1 second each were timed and averaged.\nThis was then repeated 3 times, with a new JVM each time, and the results were averaged.\n\nThe `native`, `native (simplified)`, `native (optimized)` tests each tested a hard-coded method containing the expanded,\nsimplified, and\noptimized expression, respectively.\n\n| Benchmark           | Score                  |\n|---------------------|------------------------|\n| exp4J               | 332.326 ± 15.629 ns/op |\n| parsii              | 97.120 ± 3.215 ns/op   |\n| native              | 33.003 ± 0.699 ns/op   |\n| native (simplified) | 23.084 ± 0.299 ns/op   |\n| Paralithic          | 5.541 ± 0.166 ns/op    |\n| native (optimized)  | 5.306 ± 0.114 ns/op    |\n\nResults are from tests run on an Intel i7-1165G7.\n\n\u003cdetails\u003e\n\u003csummary\u003eFull Benchmark Results\u003c/summary\u003e\n\n```\nBenchmark                                    (input)                                                                        (testExpression)  Mode  Cnt    Score    Error  Units\nPerformanceTest.exp4JPerformance                   1  (sin(x) + 2 + ((7-5) * (3.14159 * x^(14-10)) + sin(-3.141) + (0%x)) * x/3 * 3/sqrt(x))  avgt    9  336.341 ± 46.461  ns/op\nPerformanceTest.exp4JPerformance                1000  (sin(x) + 2 + ((7-5) * (3.14159 * x^(14-10)) + sin(-3.141) + (0%x)) * x/3 * 3/sqrt(x))  avgt    9  321.425 ±  9.348  ns/op\nPerformanceTest.exp4JPerformance               23422  (sin(x) + 2 + ((7-5) * (3.14159 * x^(14-10)) + sin(-3.141) + (0%x)) * x/3 * 3/sqrt(x))  avgt    9  332.326 ± 15.629  ns/op\nPerformanceTest.nativePerformance                  1  (sin(x) + 2 + ((7-5) * (3.14159 * x^(14-10)) + sin(-3.141) + (0%x)) * x/3 * 3/sqrt(x))  avgt    9   33.102 ±  0.384  ns/op\nPerformanceTest.nativePerformance               1000  (sin(x) + 2 + ((7-5) * (3.14159 * x^(14-10)) + sin(-3.141) + (0%x)) * x/3 * 3/sqrt(x))  avgt    9   33.286 ±  1.389  ns/op\nPerformanceTest.nativePerformance              23422  (sin(x) + 2 + ((7-5) * (3.14159 * x^(14-10)) + sin(-3.141) + (0%x)) * x/3 * 3/sqrt(x))  avgt    9   33.003 ±  0.699  ns/op\nPerformanceTest.nativePerformanceOptimized         1  (sin(x) + 2 + ((7-5) * (3.14159 * x^(14-10)) + sin(-3.141) + (0%x)) * x/3 * 3/sqrt(x))  avgt    9    5.301 ±  0.185  ns/op\nPerformanceTest.nativePerformanceOptimized      1000  (sin(x) + 2 + ((7-5) * (3.14159 * x^(14-10)) + sin(-3.141) + (0%x)) * x/3 * 3/sqrt(x))  avgt    9    5.257 ±  0.043  ns/op\nPerformanceTest.nativePerformanceOptimized     23422  (sin(x) + 2 + ((7-5) * (3.14159 * x^(14-10)) + sin(-3.141) + (0%x)) * x/3 * 3/sqrt(x))  avgt    9    5.306 ±  0.114  ns/op\nPerformanceTest.nativePerformanceSimplified        1  (sin(x) + 2 + ((7-5) * (3.14159 * x^(14-10)) + sin(-3.141) + (0%x)) * x/3 * 3/sqrt(x))  avgt    9   23.112 ±  0.243  ns/op\nPerformanceTest.nativePerformanceSimplified     1000  (sin(x) + 2 + ((7-5) * (3.14159 * x^(14-10)) + sin(-3.141) + (0%x)) * x/3 * 3/sqrt(x))  avgt    9   22.905 ±  0.610  ns/op\nPerformanceTest.nativePerformanceSimplified    23422  (sin(x) + 2 + ((7-5) * (3.14159 * x^(14-10)) + sin(-3.141) + (0%x)) * x/3 * 3/sqrt(x))  avgt    9   23.084 ±  0.299  ns/op\nPerformanceTest.paralithicPerformance              1  (sin(x) + 2 + ((7-5) * (3.14159 * x^(14-10)) + sin(-3.141) + (0%x)) * x/3 * 3/sqrt(x))  avgt    9    5.442 ±  0.079  ns/op\nPerformanceTest.paralithicPerformance           1000  (sin(x) + 2 + ((7-5) * (3.14159 * x^(14-10)) + sin(-3.141) + (0%x)) * x/3 * 3/sqrt(x))  avgt    9    5.432 ±  0.115  ns/op\nPerformanceTest.paralithicPerformance          23422  (sin(x) + 2 + ((7-5) * (3.14159 * x^(14-10)) + sin(-3.141) + (0%x)) * x/3 * 3/sqrt(x))  avgt    9    5.541 ±  0.166  ns/op\nPerformanceTest.parsiiPerformance                  1  (sin(x) + 2 + ((7-5) * (3.14159 * x^(14-10)) + sin(-3.141) + (0%x)) * x/3 * 3/sqrt(x))  avgt    9   97.353 ±  3.488  ns/op\nPerformanceTest.parsiiPerformance               1000  (sin(x) + 2 + ((7-5) * (3.14159 * x^(14-10)) + sin(-3.141) + (0%x)) * x/3 * 3/sqrt(x))  avgt    9   96.237 ±  2.216  ns/op\nPerformanceTest.parsiiPerformance              23422  (sin(x) + 2 + ((7-5) * (3.14159 * x^(14-10)) + sin(-3.141) + (0%x)) * x/3 * 3/sqrt(x))  avgt    9   97.120 ±  3.215  ns/op\n```\n\n\u003c/details\u003e\n\nParalithic generated the following class from the input function\n(decompiled with [Vineflower](https://vineflower.org/), a fork of FernFlower):\n\n```java\npublic class ExpressionIMPL_0 implements Expression {\n    public ExpressionIMPL_0() {\n    }\n\n    public double evaluate(Context var1, double[] var2) {\n        return TrigonometryFunctions.sin(var2[0]) + Math.fma(Math.fma(6.28318, IntegerFunctions.iPow(var2[0], 4.0), -7.669050828553736E-4) * var2[0], AlgebraFunctions.invSqrt(var2[0]), 2.0);\n    }\n}\n```\n\n## License\n\nParalithic is licensed under the [MIT License](https://github.com/PolyhedralDev/Paralithic/blob/master/LICENSE).\n\nParalithic is a \"fork\" of a [modified version](https://github.com/PolyhedralDev/parsii) of\n[Parsii](https://github.com/scireum/parsii), licensed under\nthe [MIT license](https://github.com/scireum/parsii/blob/develop/LICENSE).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpolyhedraldev%2Fparalithic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpolyhedraldev%2Fparalithic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpolyhedraldev%2Fparalithic/lists"}