{"id":23760653,"url":"https://github.com/george0st/qgate-perf","last_synced_at":"2025-04-04T10:02:10.226Z","repository":{"id":198886842,"uuid":"634246726","full_name":"george0st/qgate-perf","owner":"george0st","description":"Performance tests under quality gate solution (for python code).","archived":false,"fork":false,"pushed_at":"2024-10-24T20:04:18.000Z","size":702,"stargazers_count":128,"open_issues_count":0,"forks_count":5,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-10-25T07:43:31.666Z","etag":null,"topics":["multiprocessing","multithreading","performance-testing","python","quality-gate","testing","testset"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/george0st.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":"2023-04-29T14:14:04.000Z","updated_at":"2024-10-25T00:49:28.000Z","dependencies_parsed_at":"2024-08-28T09:37:43.818Z","dependency_job_id":"b101849d-4481-4768-95b5-799c14ad2e8d","html_url":"https://github.com/george0st/qgate-perf","commit_stats":null,"previous_names":["george0st/qgate-perf"],"tags_count":50,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/george0st%2Fqgate-perf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/george0st%2Fqgate-perf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/george0st%2Fqgate-perf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/george0st%2Fqgate-perf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/george0st","download_url":"https://codeload.github.com/george0st/qgate-perf/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247149504,"owners_count":20891954,"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":["multiprocessing","multithreading","performance-testing","python","quality-gate","testing","testset"],"created_at":"2024-12-31T20:33:11.264Z","updated_at":"2025-04-04T10:02:10.182Z","avatar_url":"https://github.com/george0st.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n[![PyPI version fury.io](https://badge.fury.io/py/qgate-perf.svg)](https://pypi.python.org/pypi/qgate-perf/)\n![coverage](https://github.com/george0st/qgate-perf/blob/main/coverage.svg?raw=true)\n![GitHub commit activity](https://img.shields.io/github/commit-activity/w/george0st/qgate-perf)\n![GitHub release](https://img.shields.io/github/v/release/george0st/qgate-perf)\n\n# QGate-Perf\n\nThe QGate Performance is enabler for python performance test execution. Key benefits:\n - **easy performance testing** your python code (key parts - init, start, stop, return)\n - **measure only specific part** of your code \n - scalability **without limits** (e.g. from 1 to 1k executors)\n - scalability **in level of processes and threads** (easy way, how to avoid GIL in python)\n - **sequences for execution and data bulk**\n - relation to graph generator\n\nNOTE: The recommendations are:\n - use Python \u003e= 3.11\n - use the 'QGate-Perf-cs' (C# implementation of QGate-Perf), in case of bigger parallelism and lower CPU spending \n\n## Usage\n\n```python\nfrom qgate_perf.parallel_executor import ParallelExecutor\nfrom qgate_perf.parallel_probe import ParallelProbe\nfrom qgate_perf.run_setup import RunSetup\nimport time\n\ndef prf_GIL_impact(run_setup: RunSetup):\n    \"\"\" Your own function for performance testing, you have to add\n    only part INIT, START, STOP and RETURN\"\"\"\n    \n    # INIT - contain executor synchronization, if needed\n    probe=ParallelProbe(run_setup)\n\n    while (True):\n        # START - probe, only for this specific code part\n        probe.start()\n\n        for r in range(run_setup.bulk_row * run_setup.bulk_col):\n            time.sleep(0)\n\n        # STOP - probe\n        if probe.stop():\n            break\n\n    # RETURN - data from probe\n    return probe\n\n# Execution setting\ngenerator = ParallelExecutor(prf_GIL_impact,\n                             label=\"GIL_impact\",\n                             detail_output=True,\n                             output_file=\"prf_gil_impact_01.txt\")\n\n# Run setup, with test execution 20 seconds and zero delay before start \n# (without waiting to other executors)\nsetup=RunSetup(duration_second=20,start_delay=0)\n\n# Run performance test with: \n#  data bulk_list with two data sets \n#    - first has 10 rows and 5 columns as [10, 5]\n#    - second has 1000 rows and 50 columns as [1000, 50]\n#  executor_list with six executor sets\n#    - first line has three executors with 2, 4 and 8 processes each with 2 threads \n#    - second line has three executors with 2, 4 and 8 processes each with 4 threads\ngenerator.run_bulk_executor(bulk_list=[[10, 5], [1000, 50]],\n                            executor_list=[[2, 2, '2x thread'], [4, 2, '2x thread'],[8, 2,'2x thread'],\n                                           [2, 4, '4x thread'], [4, 4, '4x thread'],[8, 4,'4x thread']],\n                            run_setup=setup)\n\n# Note: We made 12 performance tests (two bulk_list x six executor_list) and write \n# outputs to the file 'prf_gil_impact_01.txt'\n\n# We generate performance graph based on performance tests to the \n# directory './output/graph-perf/*' (two files each for different bundle) \ngenerator.create_graph_perf()\n```\n\n## Outputs in text file \n```\n############### 2023-05-05 06:30:36.194849 ###############\n{\"type\": \"headr\", \"label\": \"GIL_impact\", \"bulk\": [1, 1], \"available_cpu\": 12, \"now\": \"2023-05-05 06:30:36.194849\"}\n  {\"type\": \"core\", \"plan_executors\": 4, \"plan_executors_detail\": [4, 1], \"real_executors\": 4, \"group\": \"1x thread\", \"total_calls\": 7590439, \"avrg_time\": 1.4127372338382197e-06, \"std_deviation\": 3.699171006877347e-05, \"total_call_per_sec\": 2831382.8673804617, \"endexec\": \"2023-05-05 06:30:44.544829\"}\n  {\"type\": \"core\", \"plan_executors\": 8, \"plan_executors_detail\": [8, 1], \"real_executors\": 8, \"group\": \"1x thread\", \"total_calls\": 11081697, \"avrg_time\": 1.789265660825848e-06, \"std_deviation\": 4.164309967620533e-05, \"total_call_per_sec\": 4471107.994274894, \"endexec\": \"2023-05-05 06:30:52.623666\"}\n  {\"type\": \"core\", \"plan_executors\": 16, \"plan_executors_detail\": [16, 1], \"real_executors\": 16, \"group\": \"1x thread\", \"total_calls\": 8677305, \"avrg_time\": 6.2560950624827455e-06, \"std_deviation\": 8.629422798757681e-05, \"total_call_per_sec\": 2557505.8946835063, \"endexec\": \"2023-05-05 06:31:02.875799\"}\n  {\"type\": \"core\", \"plan_executors\": 8, \"plan_executors_detail\": [4, 2], \"real_executors\": 8, \"group\": \"2x threads\", \"total_calls\": 2761851, \"avrg_time\": 1.1906723084757647e-05, \"std_deviation\": 0.00010741937495211329, \"total_call_per_sec\": 671889.3135459893, \"endexec\": \"2023-05-05 06:31:10.283786\"}\n  {\"type\": \"core\", \"plan_executors\": 16, \"plan_executors_detail\": [8, 2], \"real_executors\": 16, \"group\": \"2x threads\", \"total_calls\": 3605920, \"avrg_time\": 1.858694254439209e-05, \"std_deviation\": 0.00013301637613377212, \"total_call_per_sec\": 860819.3607844017, \"endexec\": \"2023-05-05 06:31:18.740831\"}\n  {\"type\": \"core\", \"plan_executors\": 16, \"plan_executors_detail\": [4, 4], \"real_executors\": 16, \"group\": \"4x threads\", \"total_calls\": 1647508, \"avrg_time\": 4.475957498576462e-05, \"std_deviation\": 0.00020608402170105327, \"total_call_per_sec\": 357465.41393855185, \"endexec\": \"2023-05-05 06:31:26.008649\"}\n############### Duration: 49.9 seconds ###############\n```\n\n## Outputs in text file with detail\n```\n############### 2023-05-05 07:01:18.571700 ###############\n{\"type\": \"headr\", \"label\": \"GIL_impact\", \"bulk\": [1, 1], \"available_cpu\": 12, \"now\": \"2023-05-05 07:01:18.571700\"}\n     {\"type\": \"detail\", \"processid\": 12252, \"calls\": 1896412, \"total\": 2.6009109020233154, \"avrg\": 1.371490426143325e-06, \"min\": 0.0, \"max\": 0.0012514591217041016, \"st-dev\": 3.6488665183545995e-05, \"initexec\": \"2023-05-05 07:01:21.370528\", \"startexec\": \"2023-05-05 07:01:21.370528\", \"endexec\": \"2023-05-05 07:01:26.371062\"}\n     {\"type\": \"detail\", \"processid\": 8944, \"calls\": 1855611, \"total\": 2.5979537963867188, \"avrg\": 1.4000530264084008e-06, \"min\": 0.0, \"max\": 0.001207590103149414, \"st-dev\": 3.6889275786419565e-05, \"initexec\": \"2023-05-05 07:01:21.466496\", \"startexec\": \"2023-05-05 07:01:21.466496\", \"endexec\": \"2023-05-05 07:01:26.466551\"}\n     {\"type\": \"detail\", \"processid\": 2108, \"calls\": 1943549, \"total\": 2.6283881664276123, \"avrg\": 1.3523652691172758e-06, \"min\": 0.0, \"max\": 0.0012514591217041016, \"st-dev\": 3.624462003401045e-05, \"initexec\": \"2023-05-05 07:01:21.709203\", \"startexec\": \"2023-05-05 07:01:21.709203\", \"endexec\": \"2023-05-05 07:01:26.709298\"}\n     {\"type\": \"detail\", \"processid\": 19292, \"calls\": 1973664, \"total\": 2.6392557621002197, \"avrg\": 1.3372366127670262e-06, \"min\": 0.0, \"max\": 0.0041027069091796875, \"st-dev\": 3.620965943471147e-05, \"initexec\": \"2023-05-05 07:01:21.840541\", \"startexec\": \"2023-05-05 07:01:21.840541\", \"endexec\": \"2023-05-05 07:01:26.841266\"}\n  {\"type\": \"core\", \"plan_executors\": 4, \"plan_executors_detail\": [4, 1], \"real_executors\": 4, \"group\": \"1x thread\", \"total_calls\": 7669236, \"avrg_time\": 1.3652863336090071e-06, \"std_deviation\": 3.645805510967187e-05, \"total_call_per_sec\": 2929788.3539391863, \"endexec\": \"2023-05-05 07:01:26.891144\"}\n  ...\n```\n\n## Graphs generated from qgate-graph based on outputs from qgate-perf\nThe performance graph with 512 executors (128 processes x 4 threads). \nYou can see performance visualisation:\n - calls per second for different amount of executors\n - response time in seconds with standard deviation for different amount of executors \n![graph](https://github.com/george0st/qgate-perf/blob/main/assets/PRF-Calc-2023-05-06_18-22-19-bulk-1x10.png?raw=true)\nThe executor graph, you can see amount of executors in time.\n![graph](https://github.com/george0st/qgate-perf/blob/main/assets/EXE-Calc-2023-05-06_18-22-19-bulk-1x10-plan-128x4.png?raw=true)\n\n#### 32 executors (8 processes x 4 threads)\n![graph](https://github.com/george0st/qgate-perf/blob/main/assets/PRF-NoSQL_igz_nonprod-2023-04-23_14-41-18-bulk-100x50.png?raw=true)\n![graph](https://github.com/george0st/qgate-perf/blob/main/assets/EXE-NoSQL-2023-05-04_19-33-30-bulk-1x50-plan-8x2.png?raw=true)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeorge0st%2Fqgate-perf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgeorge0st%2Fqgate-perf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeorge0st%2Fqgate-perf/lists"}