{"id":13587338,"url":"https://github.com/shellspec/shellbench","last_synced_at":"2025-04-12T19:06:26.048Z","repository":{"id":47025438,"uuid":"283756068","full_name":"shellspec/shellbench","owner":"shellspec","description":"A benchmark utility for POSIX shell comparison","archived":false,"fork":false,"pushed_at":"2024-10-10T03:22:53.000Z","size":31,"stargazers_count":86,"open_issues_count":0,"forks_count":4,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-12T19:06:07.583Z","etag":null,"topics":["bash","benchmark","dash","ksh","script","shell","zsh"],"latest_commit_sha":null,"homepage":"","language":"Shell","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/shellspec.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},"funding":{"github":"ko1nksm"}},"created_at":"2020-07-30T11:36:11.000Z","updated_at":"2025-03-03T15:15:48.000Z","dependencies_parsed_at":"2024-08-01T16:33:21.262Z","dependency_job_id":null,"html_url":"https://github.com/shellspec/shellbench","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/shellspec%2Fshellbench","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shellspec%2Fshellbench/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shellspec%2Fshellbench/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shellspec%2Fshellbench/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shellspec","download_url":"https://codeload.github.com/shellspec/shellbench/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248618276,"owners_count":21134200,"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":["bash","benchmark","dash","ksh","script","shell","zsh"],"created_at":"2024-08-01T15:06:09.858Z","updated_at":"2025-04-12T19:06:26.011Z","avatar_url":"https://github.com/shellspec.png","language":"Shell","funding_links":["https://github.com/sponsors/ko1nksm"],"categories":["Shell"],"sub_categories":[],"readme":"# ShellBench\n\nA benchmark utility for POSIX shell comparison\n\n## Usage\n\n```console\nUsage: shellbench [options] files...\n\n  -s, --shell SHELL[,SHELL...]  The shell(s) to run the benchmark. [default: sh]\n  -t, --time SECONDS            Benchmark execution time. (SECONDS \u003e 0) [default: 3]\n  -w, --warmup SECONDS          Benchmark preparation time. (SECONDS \u003e 0) [default: 1]\n  -c, --correct                 Enable correction mode to eliminate loop overhead.\n  -e, --error                   Display error details.\n  -h, --help                    You're looking at it.\n```\n\n## Sample\n\n```console\n$ ./shellbench -s sh,bash,ksh,mksh,posh,zsh sample/count.sh sample/output.sh\n------------------------------------------------------------------------------------------------\nname                                   sh       bash        ksh       mksh       posh        zsh\n------------------------------------------------------------------------------------------------\ncount.sh: posix                 1,034,369    248,929    282,537    364,627    411,116    577,090\ncount.sh: typeset -i                error    237,421    288,133    341,660      error    593,124\ncount.sh: increment                 error    272,415    443,765    350,265      error    835,077\noutput.sh: echo                   279,335    121,104    375,175    179,903    201,718     59,138\noutput.sh: printf                 277,989    118,461    209,123        180        179     63,644\noutput.sh: print                    error      error    281,775    182,388      error     63,006\n------------------------------------------------------------------------------------------------\n* count: number of executions per second\n```\n\nfile: **sample/count.sh**\n\n```sh\n#!/bin/sh\n\nsetup() { i=1; }\ncleanup() { :; }\n\n#bench \"posix\"\n@begin\ni=$((i+1))\n@end\n\n#bench \"typeset -i\"\ntypeset -i i\n@begin\ni=$((i+1))\n@end\n\n#bench \"increment\"\ntypeset -i i\n@begin\n((i++))\n@end\n```\n\nfile: **sample/output.sh**\n\n```sh\n#!/bin/sh\n\n#bench \"echo\"\n@begin\necho \"test\"\n@end\n\n#bench \"printf\"\n@begin\nprintf \"test\\n\"\n@end\n\n#bench \"print\"\n@begin\nprint \"test\"\n@end\n```\n\n## Directives\n\n### `#bench`\n\nDefine new benchmark\n\n```sh\n#bench NAME\n```\n\n### @begin \u0026 @end\n\nRepeatedly execute between `@begin` to `@end`, and count the number of executions.\n\n```sh\n@begin\necho \"test\"\n@end\n```\n\n## Hooks\n\n### `setup`\n\nInvoked before each benchmark.\n\n### `cleanup`\n\nInvoked after each benchmark.\n\n## Environment variables\n\n| name                      | description                       | default |\n| ------------------------- | --------------------------------- | ------- |\n| SHELLBENCH_SHELLS         | The shell(s) to run the benchmark | sh      |\n| SHELLBENCH_BENCHMARK_TIME | Benchmark execution time          | 3       |\n| SHELLBENCH_WARMUP_TIME    | Benchmark preparation time        | 1       |\n| SHELLBENCH_NAME_WIDTH     | Display width of benchmark name   | 30      |\n| SHELLBENCH_COUNT_WIDTH    | Display width of benchamrk count  | 10      |\n| SHELLBENCH_NULLLOOP_COUNT | null loop measurement             |         |\n\n## How it works\n\nShellBench translates `@begin` and `@end` to loop as follows:\n\n```sh\n# From\n@begin\necho \"test\"\n@end\n\n# Translate to\nwhile __count=$(($__count+1)); do\necho \"test\"\ndone\n```\n\nThat is, during the benchmark time, not only `echo` but `while`, `__ count=$(($__count+1))`, count the number of times it is executed.\n\nThis loop will be killed by another process after benchmark time. Therefore, after `@end` is not executed.\n\n### Correction mode\n\nCalculate the benchmark measurement results more strictly.\nThis mode is suitable when the cost impact of the loop cannot be ignored.\n\nDifference between default and modification mode\n\n- Default mode: Measure `while`, `__count=$(($__count+1))` and target code.\n- Correction mode: Measure only target code\n\nCorrection mode first measures the null loop and then eliminates\nthe null loop measurement from the benchmark measurement.\n\n```sh\n# Null loop\nwhile __count=$(($__count+1)); do\n__CORRECTION_MODE=\ndone\n```\n\nAnd translates `@begin` and `@end` in correction mode as follows:\n\n```sh\n# From\n@begin\necho \"test\"\n@end\n\n# Translate to\nwhile __count=$(($__count+1)); do\n__CORRECTION_MODE=\necho \"test\"\ndone\n```\n\nCompute a corrected value from the null loop execution count and the benchmark count.\n\nCorrected count: `B / ( 1.0 - ( B * ( 1.0 / A ) ) )`\n\n- A: null loop executed count\n- B: benchmark count\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshellspec%2Fshellbench","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshellspec%2Fshellbench","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshellspec%2Fshellbench/lists"}