{"id":18364179,"url":"https://github.com/boxbeam/crunch","last_synced_at":"2025-04-06T15:32:21.014Z","repository":{"id":37616626,"uuid":"332316261","full_name":"boxbeam/Crunch","owner":"boxbeam","description":"The fastest java expression compiler/evaluator","archived":false,"fork":false,"pushed_at":"2024-02-05T16:56:45.000Z","size":276,"stargazers_count":73,"open_issues_count":0,"forks_count":9,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-22T02:51:17.192Z","etag":null,"topics":["evaluating-mathematical-expressions","evaluations"],"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/boxbeam.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}},"created_at":"2021-01-23T21:58:31.000Z","updated_at":"2025-03-20T18:03:28.000Z","dependencies_parsed_at":"2023-01-20T22:47:31.320Z","dependency_job_id":"aee8d7df-d3d6-44b6-ac8b-9a9eb003a47f","html_url":"https://github.com/boxbeam/Crunch","commit_stats":null,"previous_names":["boxbeam/crunch"],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boxbeam%2FCrunch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boxbeam%2FCrunch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boxbeam%2FCrunch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boxbeam%2FCrunch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/boxbeam","download_url":"https://codeload.github.com/boxbeam/Crunch/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247503022,"owners_count":20949370,"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":["evaluating-mathematical-expressions","evaluations"],"created_at":"2024-11-05T23:09:32.761Z","updated_at":"2025-04-06T15:32:20.769Z","avatar_url":"https://github.com/boxbeam.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Crunch\nThe fastest Java expression compiler/evaluator\n\nSupport Discord: https://discord.gg/agu5xGy2YZ\n\n# Installation for Development\n\nCrunch can be accessed via my build server using Gradle or Maven. Read the section for whichever you use below.\n\n## Gradle:\n\n```\t\t\nrepositories {\n\tmaven { url 'https://redempt.dev' }\n}\n\n```\n\n```\ndependencies {\n\timplementation 'com.github.Redempt:Crunch:Tag'\n}\n```\n\nReplace `Tag` with a version, like `1.0`.\n\n## Maven:\n\n```\n\u003crepository\u003e\n\t\u003cid\u003eredempt.dev\u003c/id\u003e\n\t\u003curl\u003ehttps://redempt.dev\u003c/url\u003e\n\u003c/repository\u003e\n```\n\n```\n\u003cdependency\u003e\n\t\u003cgroupId\u003ecom.github.Redempt\u003c/groupId\u003e\n\t\u003cartifactId\u003eCrunch\u003c/artifactId\u003e\n\t\u003cversion\u003eTag\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nReplace `Tag` with a version, like `1.0`.\n\n# Usage\n\nCrunch offers a better solution to evaluating complex mathematical expressions than using ScriptManager. It is simple to use, performant, and lightweight.\n\nThere are only a handful of methods you will need to use in Crunch. To compile an expression, simply call `Crunch#compileExpression`. Here's an example:\n\n```java\nCompiledExpression exp = Crunch.compileExpression(\"1 + 1\");\nexp.evaluate(); //This will return 2\n```\n\nYou can use all the basic operations you're familiar with. If you want to see a list of all supported operations, check the [Operator](https://github.com/Redempt/Crunch/blob/master/src/redempt/crunch/Operator.java) enum, or the Operations section below.\n\nVariables can also be used with Crunch. They must be numbered, starting with 1, and preceded by a `$`. This is part of what makes Crunch so performant. If you need named variables, however, you can specify names for them with an `EvaluationEnvironment`. When calling `evaluate` on a CompiledExpression with variables, you must pass them in order of index.\n\n```java\nCompiledExpression exp = Crunch.compileExpression(\"$1 / $2\");\nexp.evaluate(27, 3); //This will return 9\n```\n\nSpaces are ignored entirely, so if you don't feel the need to add them, you may remove them.\n\nYou can also define your own functions fairly simply:\n\n```java\nEvaluationEnvironment env = new EvaluationEnvironment();\n//                name  # args   lambda to do logic\nenv.addFunction(\"mult\", 2, (d) -\u003e d[0] * d[1]);\nCompiledExpression exp = Crunch.compileExpression(\"mult(2, 3)\", env);\nexp.evaluate(); //This will return 6\n```\n\nWith an EvaluationEnvironment, you're also able to specify names for your variables:\n\n```java\nEvaluationEnvironment env = new EvaluationEnvironment();\nenv.setVariableNames(\"x\", \"y\");\nCompiledExpression exp = Crunch.compileExpression(\"x - y\", env);\nexp.evaluate(3, 4); //This will return -1\n```\n\nThe values for the variables must be passed in the same order that you passed the variable names in.\n\nYou're also able to define lazy variables, which don't need to be passed as arguments to `evaluate`:\n\n```java\nEvaluationEnvironment env = new EvaluationEnvironment();\nenv.addLazyVariable(\"x\", () -\u003e 4);\nCompiledExpression exp = Crunch.compileExpression(\"x + 1\", env);\nexp.evaluate(); //This will return 5\n```\n\nIn the case that you only need to evaluate an expression once and never again, you can use `Crunch#evaluateExpression`:\n\n```java\nint exampleVar = 50;\nCrunch.evaluateExpression(\"abs(3 - $1)\", exampleVar);\n```\n\nHowever, if the expression will be used more than once, it is highly recommended to keep it as a `CompiledExpression` instead.\n\nCompiledExpressions are NOT thread-safe, and may have issues if `evaluate` is called from multiple threads at the same time. For multi-threaded purposes, please mutex your CompiledExpression or clone it with `CompiledExpression#clone` and pass it off to another thread.\n\n# Performance\n\nPerformance is one of the largest benefits of using Crunch. It is designed to be extremely performant, and lives up to that expectation. For cases where you need to perform a lot of evaluations quickly from a string-compiled mathematical expression, Crunch is the best option.\n\nHere I will compare the runtimes of Crunch against two similar librararies: [EvalEx](https://github.com/uklimaschewski/EvalEx) and [exp4j](https://github.com/fasseg/exp4j). I will compare both compilation times and evaluation times.\n\nCPU: AMD Ryzen 7 5800X\n\nBenchmark source: https://github.com/Redempt/CrunchBenchmark\n\n## Compilation\nSimple expression: `3*5`\nComplex expression: `6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4 + 6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4 + 6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4 + 6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4`\n```\nBenchmark                                        Mode      Score     Error  Units\nCompileBenchmark.crunchCompileComplexExpression  avgt      2.974 ±   0.033  us/op\nCompileBenchmark.crunchCompileSimpleExpression   avgt      0.050 ±   0.001  us/op\nCompileBenchmark.evalExCompileComplexExpression  avgt     38.450 ±   0.526  us/op\nCompileBenchmark.evalExCompileSimpleExpression   avgt      9.156 ±   0.256  us/op\nCompileBenchmark.exp4jCompileComplexExpression   avgt      3.464 ±   0.026  us/op\nCompileBenchmark.exp4jCompileSimpleExpression    avgt      0.276 ±   0.009  us/op\n```\n\n## Evaluation\n\nSimple expression: `(10*x)+5/2`\nConstant expression: `6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4 + 6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4 + 6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4 + 6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4`\n\n```\nBenchmark                                        Mode      Score     Error  Units\nEvalBenchmark.crunchConstantEval                 avgt      0.823 ±   0.020  ns/op\nEvalBenchmark.crunchSimpleEval                   avgt      4.296 ±   0.058  ns/op\nEvalBenchmark.evalExConstantEval                 avgt  26156.342 ± 183.188  ns/op\nEvalBenchmark.evalExSimpleEval                   avgt   2283.572 ±  19.630  ns/op\nEvalBenchmark.exp4jConstantEval                  avgt    540.194 ±   4.434  ns/op\nEvalBenchmark.exp4jSimpleEval                    avgt     44.727 ±   0.554  ns/op\n```\n\n# Operations and Syntax\n\n`()` - Create a parenthetical expression which will be evaluated first (`3 * (4 + 1)`)\n\n`$` - Denotes a variable (`$1 / 3`)\n\n`e` - Euler's constant (`log(e)`)\n\n`pi` - pi (`sin(pi)`)\n\n`+` - Add two numbers (`1 + 1`)\n\n`-` - Subtract two numbers, or negate one (`3-2`, `-(4+2)`)\n\n`/` - Divide two numbers (`3 / 4`)\n\n`*` - Multiply two numbers (`2 * 3`)\n\n`^` - Raise one number to the power of another (`3^3`)\n\n`%` - Take the modulus, or division remainder, of one number with another (`7 % 4`)\n\n`abs` - Take the absolute value of a number (`abs$1`, `abs-1`)\n\n`round` - Rounds a number to the nearest integer (`round1.5`, `round(2.3)`)\n\n`ceil` - Rounds a number up to the nearest integer (`ceil1.05`)\n\n`floor` - Rounds a number down to the nearest integer (`floor0.95`)\n\n`rand` - Generate a random number between 0 and the specified upper bound (`rand4`)\n\n`log` - Get the natural logarithm of a number (`log(e)`)\n\n`sqrt` - Get the square root of a number (`sqrt4`)\n\n`cbrt` - Get the cube root of a number (`cbrt(8)`)\n\n`sin` - Get the sine of a number (`sin$2`)\n\n`cos` - Get the cosine of a number (`cos(2*pi)`)\n\n`tan` - Get the tangent of a number (`tanpi`)\n\n`asin` - Get the arcsine of a number (`asin$2`)\n\n`acos` - Get the arccosine of a number (`acos0.45`)\n\n`atan` - Get the arctangent of a number (`atan1`)\n\n`sinh` - Get the hyperbolic sine of a number (`sinh(4)`)\n\n`cosh` - Get the hyperbolic cosine of a number (`sinh(4)`)\n\n`true` - Boolean constant representing 1\n\n`false` - Boolean constant representing 0\n\n`=` - Compare if two numbers are equal (`1 = 1` will be `1`, `1 = 3` will be `0`), also accepts `==`\n\n`!=` - Compare if two numbers are not equal (`1 != 2` will be `1`, `1 != 1` will be `0`)\n\n`\u003e` - Compare if one number is greater than another (`1 \u003e 0`)\n\n`\u003c` - Compare if one number is less than another (`0 \u003c 1`)\n\n`\u003e=` - Compare if one number is greater than or equal to another (`1 \u003e= 1`)\n\n`\u003c=` - Compare if one number is less than or equal to another (`0 \u003c= 1`)\n\n`|` - Boolean or (`true | false`), also accepts `||`\n\n`\u0026` - Boolean and (`true \u0026 true`), also accepts `\u0026\u0026`\n\n`!` - Boolean not/inverse (`!true`)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fboxbeam%2Fcrunch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fboxbeam%2Fcrunch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fboxbeam%2Fcrunch/lists"}