{"id":17144118,"url":"https://github.com/szabolcsdombi/optimization-demo-rust","last_synced_at":"2026-05-02T08:34:59.816Z","repository":{"id":180140578,"uuid":"664650100","full_name":"szabolcsdombi/optimization-demo-rust","owner":"szabolcsdombi","description":"Optimizing Python code by calling into Rust","archived":false,"fork":false,"pushed_at":"2023-07-11T09:15:38.000Z","size":18,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-24T10:17:31.270Z","etag":null,"topics":["benchmark","cpp","python","rust"],"latest_commit_sha":null,"homepage":"","language":"C++","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/szabolcsdombi.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-07-10T12:52:54.000Z","updated_at":"2023-07-19T19:53:00.000Z","dependencies_parsed_at":"2024-02-18T04:00:38.535Z","dependency_job_id":null,"html_url":"https://github.com/szabolcsdombi/optimization-demo-rust","commit_stats":null,"previous_names":["szabolcsdombi/c-rust-python"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/szabolcsdombi/optimization-demo-rust","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/szabolcsdombi%2Foptimization-demo-rust","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/szabolcsdombi%2Foptimization-demo-rust/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/szabolcsdombi%2Foptimization-demo-rust/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/szabolcsdombi%2Foptimization-demo-rust/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/szabolcsdombi","download_url":"https://codeload.github.com/szabolcsdombi/optimization-demo-rust/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/szabolcsdombi%2Foptimization-demo-rust/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32528416,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-02T01:12:54.858Z","status":"online","status_checked_at":"2026-05-02T02:00:05.923Z","response_time":132,"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","cpp","python","rust"],"created_at":"2024-10-14T20:43:08.021Z","updated_at":"2026-05-02T08:34:59.799Z","avatar_url":"https://github.com/szabolcsdombi.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# optimization-demo-rust\n\nThis is an extension to my original [optimization-demo](https://github.com/szabolcsdombi/optimization-demo) article.\n\nThe previous article was about optimizing a tiny bit of Python code by replacing it with its C++ counterpart.\n\nIn this article we will replace the C++ code with a call into a library built with Rust.\n\nLet's get started by implementing the opening handshake in Rust.\n\n```rust\nuse sha1::Sha1;\nuse sha1::Digest;\n\npub fn sec_websocket_accept(key: \u0026str) -\u003e String {\n    let mut concat_key = String::with_capacity(key.len() + 36);\n    concat_key.push_str(\u0026key[..]);\n    concat_key.push_str(\"258EAFA5-E914-47DA-95CA-C5AB0DC85B11\");\n    let hash = Sha1::digest(concat_key.as_bytes());\n    base64::encode(hash.as_slice())\n}\n```\n\nThe Python we are using is [cpython](https://github.com/python/cpython), hence the name suggests the interpreter is implemented in C and it can call into C/C++ code very easily.\nLuckily Rust can expose a C api and build a static library accessible from C/C++.\nTo do so we need to add an exported method.\n\n```rust\n#[no_mangle]\npub extern fn rust_accept(key: *const u8, result: *mut u8) {\n    unsafe {\n        let source = std::slice::from_raw_parts(key, 24);\n        let source_str = std::str::from_utf8_unchecked(source);\n        let modified_str = sec_websocket_accept(source_str);\n        let dest = std::slice::from_raw_parts_mut(result, 28);\n        dest[..28].copy_from_slice(modified_str.as_bytes());\n    }\n}\n```\n\nAnd on the C++ side we can add an extern function.\n\n```c++\nextern \"C\" void rust_accept(const char * key, char * result);\n```\n\nCalling this function from C++ will call into our Rust code.\n\n```c++\nPyObject * meth_rust_accept(PyObject * self, PyObject * arg) {\n    char result[28];\n    Py_ssize_t len = 0;\n    const char * key = PyUnicode_AsUTF8AndSize(arg, \u0026len);\n    if (!key || len != 24) {\n        PyErr_SetString(PyExc_ValueError, \"invalid key\");\n        return NULL;\n    }\n    rust_accept(key, result);\n    return PyUnicode_FromStringAndSize(result, 28);\n}\n```\n\nNow we have two methods available:\n\n- the first one calls `sec_websocket_accept()` implemented in C++\n- the second calls `sec_websocket_accept()` implemented in Rust\n\nAll the other code, including validation, is identical.\n\nWe can now extend the [test.py](test.py) and see the results.\n\n```py\nfrom mymodule import c_accept, rust_accept\n\n\ndef test_optimized_code(benchmark):\n    assert benchmark(c_accept, 'dGhlIHNhbXBsZSBub25jZQ==') == 's3pPLMBiTxaQ9kYGzzhZRbK+xOo='\n\n\ndef test_rust_code(benchmark):\n    assert benchmark(rust_accept, 'dGhlIHNhbXBsZSBub25jZQ==') == 's3pPLMBiTxaQ9kYGzzhZRbK+xOo='\n```\n\n## Results\n\n```\n--------------------------------------------------------------------------------------------------------\nName (time in ns)           Mean            StdDev              Median            OPS (Mops/s)\n--------------------------------------------------------------------------------------------------------\ntest_optimized_code     207.8409 (1.0)      0.2554 (1.83)     207.8076 (1.0)            4.8114 (1.0)\ntest_rust_code          332.9054 (1.60)     0.1394 (1.0)      332.8895 (1.60)           3.0039 (0.62)\ntest_python_code        913.2048 (4.39)     3.5578 (25.52)    912.7434 (4.39)           1.0950 (0.23)\n--------------------------------------------------------------------------------------------------------\n```\n\n## Conclusion\n\nAccording to the results the C++ implementation is around 1.6x times faster than the Rust implementation.\nThe two should be on par, except that that Rust needs additional work to expose a C api.\n\n## Notes\n\nI want to highlight that we are not comparing these languages directly.\n\nThe goal is to have a Pythonic method with the following signature:\n\n```py\ndef websocket_accept(key: str) -\u003e str: ...\n```\n\nThe method itself will not be implemented in Python, but it will be **available** in Python.\n\nI could not build a Python extension with only using Rust.\nI have implemented the simplest way to get the Rust implementation working from Python.\nIf there is a better way please feel free to make a pull request.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fszabolcsdombi%2Foptimization-demo-rust","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fszabolcsdombi%2Foptimization-demo-rust","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fszabolcsdombi%2Foptimization-demo-rust/lists"}