{"id":34017416,"url":"https://github.com/manzik/cmdbench","last_synced_at":"2025-12-13T14:33:58.325Z","repository":{"id":56452889,"uuid":"267114874","full_name":"manzik/cmdbench","owner":"manzik","description":"Quick and easy resource usage monitoring and benchmarking for any command's CPU, memory, disk usage and runtime.","archived":false,"fork":false,"pushed_at":"2025-02-02T03:47:09.000Z","size":21736,"stargazers_count":36,"open_issues_count":1,"forks_count":6,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-09-10T08:04:08.868Z","etag":null,"topics":["benchmark","benchmarking","disk-usage","memory-usage","usage"],"latest_commit_sha":null,"homepage":"","language":"Python","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/manzik.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}},"created_at":"2020-05-26T18:00:08.000Z","updated_at":"2025-08-27T12:23:30.000Z","dependencies_parsed_at":"2022-08-15T19:00:56.416Z","dependency_job_id":null,"html_url":"https://github.com/manzik/cmdbench","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/manzik/cmdbench","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manzik%2Fcmdbench","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manzik%2Fcmdbench/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manzik%2Fcmdbench/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manzik%2Fcmdbench/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/manzik","download_url":"https://codeload.github.com/manzik/cmdbench/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manzik%2Fcmdbench/sbom","scorecard":{"id":616200,"data":{"date":"2025-08-11","repo":{"name":"github.com/manzik/cmdbench","commit":"3afb175763894260bda5ad713cb508ec0cf60cbc"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.5,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/26 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":9,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/release.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":9,"reason":"binaries present in source code","details":["Warn: binary detected: tests/disk/read_binary_test:1"],"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/manzik/cmdbench/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/manzik/cmdbench/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:48: update your workflow using https://app.stepsecurity.io/secureworkflow/manzik/cmdbench/release.yml/main?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/release.yml:29","Warn: pipCommand not pinned by hash: .github/workflows/release.yml:30","Warn: pipCommand not pinned by hash: .github/workflows/release.yml:39","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   0 out of   3 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/release.yml:10"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 7 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-21T04:02:13.278Z","repository_id":56452889,"created_at":"2025-08-21T04:02:13.278Z","updated_at":"2025-08-21T04:02:13.278Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27707159,"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","status":"online","status_checked_at":"2025-12-13T02:00:09.769Z","response_time":147,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["benchmark","benchmarking","disk-usage","memory-usage","usage"],"created_at":"2025-12-13T14:33:57.627Z","updated_at":"2025-12-13T14:33:58.316Z","avatar_url":"https://github.com/manzik.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Deployment](https://github.com/manzik/cmdbench/actions/workflows/release.yml/badge.svg)](https://github.com/manzik/cmdbench/actions/workflows/release.yml)  \n# CMDBench\nA quick and easy benchmarking tool for any command's CPU, memory and disk usage.  \nCLI and the library functionalities are both provided.  \n\nNote: This library is written in, heavily tested, and maintained for the **Linux** operating system primarily. But **Windows** and **macOS** are also supported. Create an issue in case you run into a problem. \n## Install\nTo install the library from PyPI, execute the following command in your terminal: \n```bash\npip install cmdbench\n```\nPython compatibility: \u003e=3.6\n# Table of contents\n   * [Quick Start: Command Line Interface](#quick-start-command-line-interface)\n   * [Quick Start: Library](#quick-start-library)\n      * [Method 1: Easier](#method-1-easier)\n      * [Method 2: More customizable](#method-2-more-customizable)\n      * [Usage IPython Notebook](#usage-ipython-notebook)\n   * [Documentation](#documentation)\n      * [benchmark_command: method](#benchmark_commandcommand-str-iterations_num--1-raw_data--false)\n      * [benchmark_command_generator: method](#benchmark_command_generatorcommand-str-interations_num--1-raw_data--false)\n      * [BenchmarkResults: Class](#benchmarkresults-class)\n      * [BenchmarkDict: Class](#benchmarkdict-classdefaultdict)\n   * [Notes](#notes)\n      * [macOS](#macos)\n      * [Windows](#windows)\n      \n# Quick Start: Command Line Interface\nYou can use the CLI provided by the python package to benchmark any command.  \nIn the following demo, the command `node test.js` (a slightly modified version of [test.js](test.js)) is being benchmarked 10 times, average of resources are being printed and a plot for the command's cpu and memory usage is being saved to the file `plot.png`.  \n\n[![Usage demo](https://github.com/manzik/cmdbench/raw/main/resources/cmdbench.svg?sanitize=true)](https://asciinema.org/a/25Juo57eeSrNVJPa7rJiokW78)  \n\nThe output plot file `plot.png` for the demo will look like:  \n\n![Resources plot](https://github.com/manzik/cmdbench/raw/main/resources/plot.png)  \n\n# Quick Start: Library  \n\n## Method 1: Easier  \nYou can simply use the `benchmark_command` function to benchmark a command.\nBenchmarks the command `stress --cpu 10 --timeout 5` over 20 iterations. But prints only the first one from the benchmark results.\n```python\n\u003e\u003e\u003e import cmdbench\n\u003e\u003e\u003e benchmark_results = cmdbench.benchmark_command(\"stress --cpu 10 --timeout 5\", iterations_num = 20)\n\u003e\u003e\u003e first_iteration_result = benchmark_results.get_first_iteration()\n\u003e\u003e\u003e first_iteration_result\n{\n  'cpu': {\n    'system_time': 0.04,\n    'total_time': 49.75,\n    'user_time': 49.71,\n  },\n  'disk': {\n    'read_bytes': 0,\n    'read_chars': 5124,\n    'total_bytes': 0,\n    'total_chars': 5243,\n    'write_bytes': 0,\n    'write_chars': 119,\n  },\n  'memory': {\n    'max': 2166784,\n    'max_perprocess': 1060864,\n  },\n  'process': {\n    'execution_time': 5.0,\n    'stderr_data': '',\n    'stdout_data': 'stress: info: [20773] dispatching hogs: 10 cpu, 0 io, 0 vm, 0 hdd\\n\\nstress: info: [20773] successful run\n                    completed in 5s\\n',\n  },\n  'time_series': {\n    'cpu_percentages': array([  0. ,   0. , 824.1, ..., 889. , 998.3,   0. ])\n    'memory_bytes': array([2166784, 2166784, 2166784, ..., 2166784, 2166784, 1060864])\n    'sample_milliseconds': array([  39,   54,   65, ..., 4979, 4988, 4997])\n  },\n}\n\u003e\u003e\u003e first_iteration_result.process.execution_time\n5.0\n```\n## Method 2: More customizable  \nYou can also create one or more BenchmarkResults objects, and add benchmark results to them over time.  \nSo you are not forced to perform the benchmarking for the command consecutively when you simply can't.  \nCould be helpful when you are trying to benchmark multiple commands that need to be executed in a certain order consecutively or depend on each other.\n```python\n\u003e\u003e\u003e from cmdbench import benchmark_command, BenchmarkResults\n\u003e\u003e\u003e benchmark_results = BenchmarkResults()\n\u003e\u003e\u003e for _ in range(20):\n...   new_benchmark_result = cmdbench.benchmark_command(\"stress --cpu 10 --timeout 5\")\n...   benchmark_results.add_benchmark_result(new_benchmark_result)\n... # The for loop above is equivalent to: benchmark_results = cmdbench.benchmark_command(\"stress --cpu 10 --timeout 5\", iterations_num = 20)\n\u003e\u003e\u003e benchmark_results.get_averages()\n{\n  'cpu': {\n    'system_time': 0.012500000000000002,\n    'total_time': 48.468,\n    'user_time': 48.45550000000001,\n  },\n  'disk': {\n    'read_bytes': 0.0,\n    'read_chars': 5124.0,\n    'total_bytes': 0.0,\n    'total_chars': 5232.4,\n    'write_bytes': 0.0,\n    'write_chars': 108.4,\n  },\n  'memory': {\n    'max': 2094080.0,\n    'max_perprocess': 1020928.0,\n  },\n  'process': {\n    'execution_time': 5.0,\n    'stderr_data': None,\n    'stdout_data': None,\n  },\n  'time_series': {\n    'cpu_percentages': array([  0.        , 476.03157895, 794.66363636, ..., 976.05555556,\n       188.97777778,   0.        ])\n    'memory_bytes': array([2093924.84848485, 2096074.10526316, 2099013.81818182, ...,\n       2090552.88888889, 1256561.77777778,  810188.8       ])\n    'sample_milliseconds': array([  11.42424242,   21.73684211,   30.90909091, ..., 4986.44444444,\n       4995.05555556, 5000.2       ])\n  },\n}\n```\n## Usage IPython notebook  \nFor a more comprehensive demonstration on how to use the library and the resources plot, check the provided [ipython notebook](benchmark-usage.ipynb). \n\n# Documentation  \n\n## benchmark_command(command: str, iterations_num = 1, raw_data = False)  \n  - Arguments\n    - command: Target command to process.\n    - iterations_num: Number of times to measure the program's resources.\n    - raw_data: Whether or not to show all different info from different sources like psutil and GNU Time (if available).\n  - Returns a BenchmarkResults object containing the related results.\n\n## benchmark_command_generator(command: str, interations_num = 1, raw_data = False)\n  - Arguments: Same as benchmark_command\n  - Returns a [generator](https://wiki.python.org/moin/Generators) object allowing you to obtain a BenchmarkResults after each iteration of benchmarking until done (useful for monitoring the progress and recieving benchmarking data on the go).\n\n## BenchmarkResults: Class\n  - Methods:\n    - `get_first_iteration()`  \n      Returns the first iteration result in the benchmark results object.\n    - `get_iterations()`  \n      Returns the result for all of the iterations in the benchmark results object.\n    - `get_values_per_attribute()`  \n      Returns object containing lists for each type of value over different iterations. \n    - `get_averages()`  \n      Returns the average for all types of value over different iterations. Also calculates the average of the time series data.\n    - `get_statistics()`  \n      Returns different statistics (mean, stdev, min, max) for all types of values over different iterations.\n    - `get_resources_plot(width: int, height: int)`  \n      Returns matplotlib figure object of CPU and Memory usage of target process over time which can be viewed in an ipython notebook or be saved to an image file.\n    - `add_benchmark_result(adding_result: BenchmarkResults)`  \n      Adds another BenchmarkResults object's benchmark results iterations' data to the current object.\n\n## BenchmarkDict: Class(defaultdict)\n  A custom internal dictionary class used to represent the data for an iteration.  \n  Data inside objects from this class are accessible through both dot notation `obj.key` and key access `obj[\"key\"]`\n\n# Notes\n\n## Windows\nWhen benchmarking on windows, you will need to wrap your main code around the `if __name__ == '__main__':` statement.\n\n## MacOS\nMacOS does not allow process-specific disk usage information collection, therefore disk usage will not be reported on macOS when you perform benchmarking.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmanzik%2Fcmdbench","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmanzik%2Fcmdbench","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmanzik%2Fcmdbench/lists"}