{"id":17899604,"url":"https://github.com/totomanov/sortnet","last_synced_at":"2025-03-23T13:31:44.899Z","repository":{"id":234270408,"uuid":"788549318","full_name":"totomanov/sortnet","owner":"totomanov","description":"Gas-optimized sorting networks in Solidity.","archived":false,"fork":false,"pushed_at":"2024-05-24T10:23:55.000Z","size":52,"stargazers_count":15,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-18T20:48:25.558Z","etag":null,"topics":["ethereum","solidity","sorting-network"],"latest_commit_sha":null,"homepage":"","language":"Solidity","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/totomanov.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":"2024-04-18T16:24:05.000Z","updated_at":"2025-03-18T10:01:08.000Z","dependencies_parsed_at":"2024-04-18T18:16:41.400Z","dependency_job_id":"61c4b835-1ffe-4d20-b678-b42517a5d2e2","html_url":"https://github.com/totomanov/sortnet","commit_stats":null,"previous_names":["totomanov/sortnet"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/totomanov%2Fsortnet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/totomanov%2Fsortnet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/totomanov%2Fsortnet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/totomanov%2Fsortnet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/totomanov","download_url":"https://codeload.github.com/totomanov/sortnet/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245108205,"owners_count":20562006,"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":["ethereum","solidity","sorting-network"],"created_at":"2024-10-28T16:00:13.809Z","updated_at":"2025-03-23T13:31:44.532Z","avatar_url":"https://github.com/totomanov.png","language":"Solidity","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Sortnet\n\nSort fixed-size Solidity arrays in an extremely gas-efficient way.\n\nFor arrays of size 2-10 `LibSortNet` consumes 30–60% less gas than insertion sort in [Solady](https://github.com/Vectorized/solady).\n\n## Introduction\n\nA _sorting network_ is a sequence of operations that sorts an array in place. Each operation compares two elements and swaps them conditionally.\n\n### Example\n\n`(0,2),(0,1),(1,2)` is a sorting network for an array of length 3.\n\n```solidity\n[1 2 0] --(0,2)-\u003e [0 2 1] --(0,1)-\u003e [0 2 1] --(1,2)-\u003e [0 1 2]\n[2 0 1] --(0,2)-\u003e [1 0 2] --(0,1)-\u003e [0 1 2] --(1,2)-\u003e [0 1 2]\n[2 1 0] --(0,2)-\u003e [0 1 2] --(0,1)-\u003e [0 1 2] --(1,2)-\u003e [0 1 2]\n```\n\n## Resources\n\n[Introduction to Sorting Networks (Doug Hoyte)](https://hoytech.github.io/sorting-networks/)\n\n[List of Sorting Networks (Bert Dobbelaere)](https://bertdobbelaere.github.io/sorting_networks.html)\n\n## Installation\n\nTo install with [**Foundry**](https://github.com/foundry-rs/foundry):\n\n```sh\nforge install totomanov/sortnet\n```\n\n## Usage\n\n#### `function sort*(uint256[] memory a) internal pure`\n\nSorts a `uint256[] memory` array in-place. The size must be known beforehand and must be between 3 and 32.\n\n#### `function median*(uint256[] memory a) internal pure returns (uint256 m)`\n\nReturns the median of a `uint256[] memory` array with known size. The size must be known beforehand and must be between 3 and 32.\n\n## Benchmark\n\n```sh\nforge test --match-test Bench -vvv\n```\n\n### Gas table\n\n| size | `@sortnet/LibSortNet::sort*` | `@solady/LibSort::insertionSort` | `@solady/LibSort::sort` |\n| ---- | ---------------------------- | -------------------------------- | ----------------------- |\n| 2    | 55                           | 298                              | 475                     |\n| 3    | 153                          | 489                              | 848                     |\n| 4    | 268                          | 709                              | 1190                    |\n| 5    | 445                          | 970                              | 1485                    |\n| 6    | 627                          | 1257                             | 1796                    |\n| 7    | 837                          | 1577                             | 2126                    |\n| 8    | 1076                         | 1940                             | 2495                    |\n| 9    | 1331                         | 2323                             | 2907                    |\n| 10   | 1548                         | 2731                             | 3321                    |\n| 11   | 2376                         | 3194                             | 3771                    |\n| 12   | 2724                         | 3690                             | 4287                    |\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ci\u003eData\u003c/i\u003e\u003c/summary\u003e\n\nCompiled with:\n\n```toml\nsolc = \"0.8.25\"\noptimizer = true\noptimizer_runs = 20_000\nvia-ir = true\n```\n\n```\n[PASS] testBench_sort10() (gas: 79892301)\nLogs:\n  LibSortNet::sort10 (min: 1301, max: 1747, ~: 1548)\n  LibSort::insertionSort (min: 1544, max: 3916, ~: 2731)\n  LibSort::sort (min: 2187, max: 4465, ~: 3321)\n\n[PASS] testBench_sort11() (gas: 82209683)\nLogs:\n  LibSortNet::sort11 (min: 2038, max: 2795, ~: 2376)\n  LibSort::insertionSort (min: 1925, max: 4640, ~: 3194)\n  LibSort::sort (min: 2464, max: 5195, ~: 3771)\n\n[PASS] testBench_sort12() (gas: 83912304)\nLogs:\n  LibSortNet::sort12 (min: 2242, max: 3083, ~: 2724)\n  LibSort::insertionSort (min: 2137, max: 4970, ~: 3690)\n  LibSort::sort (min: 2895, max: 5973, ~: 4287)\n\n[PASS] testBench_sort2() (gas: 69401423)\nLogs:\n  LibSortNet::sort2 (min: 40, max: 71, ~: 55)\n  LibSort::insertionSort (min: 268, max: 327, ~: 298)\n  LibSort::sort (min: 397, max: 553, ~: 475)\n\n[PASS] testBench_sort3() (gas: 70648831)\nLogs:\n  LibSortNet::sort3 (min: 118, max: 179, ~: 153)\n  LibSort::insertionSort (min: 397, max: 582, ~: 489)\n  LibSort::sort (min: 463, max: 1103, ~: 848)\n\n[PASS] testBench_sort4() (gas: 71668024)\nLogs:\n  LibSortNet::sort4 (min: 196, max: 347, ~: 268)\n  LibSort::insertionSort (min: 526, max: 904, ~: 709)\n  LibSort::sort (min: 529, max: 1479, ~: 1190)\n\n[PASS] testBench_sort5() (gas: 72985853)\nLogs:\n  LibSortNet::sort5 (min: 353, max: 556, ~: 445)\n  LibSort::insertionSort (min: 655, max: 1293, ~: 970)\n  LibSort::sort (min: 595, max: 1928, ~: 1485)\n\n[PASS] testBench_sort6() (gas: 74107595)\nLogs:\n  LibSortNet::sort6 (min: 469, max: 769, ~: 627)\n  LibSort::insertionSort (min: 784, max: 1749, ~: 1257)\n  LibSort::sort (min: 933, max: 2444, ~: 1796)\n\n[PASS] testBench_sort7() (gas: 75553028)\nLogs:\n  LibSortNet::sort7 (min: 670, max: 1000, ~: 837)\n  LibSort::insertionSort (min: 1031, max: 2272, ~: 1577)\n  LibSort::sort (min: 1479, max: 2893, ~: 2126)\n\n[PASS] testBench_sort8() (gas: 76872860)\nLogs:\n  LibSortNet::sort8 (min: 889, max: 1303, ~: 1076)\n  LibSort::insertionSort (min: 1101, max: 2736, ~: 1940)\n  LibSort::sort (min: 1732, max: 3435, ~: 2495)\n\n[PASS] testBench_sort9() (gas: 78513806)\nLogs:\n  LibSortNet::sort9 (min: 1113, max: 1523, ~: 1331)\n  LibSort::insertionSort (min: 1356, max: 3192, ~: 2323)\n  LibSort::sort (min: 1963, max: 3977, ~: 2907)\n```\n\n\u003c/details\u003e\n\n## Safety\n\nThis is **experimental software** and is provided on an \"as is\" and \"as available\" basis.\n\nWe **do not give any warranties** and **will not be liable for any loss** incurred through any use of this codebase.\n\nPlease always include your own thorough tests when using Sortnet to make sure it works correctly with your code.\n\n## Acknowledgements\n\n[hoytech](https://github.com/hoytech) and [Solady](https://github.com/Vectorized/solady)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftotomanov%2Fsortnet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftotomanov%2Fsortnet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftotomanov%2Fsortnet/lists"}