{"id":18498350,"url":"https://github.com/softdevteam/vtable_bench","last_synced_at":"2025-05-14T05:22:04.159Z","repository":{"id":147040294,"uuid":"169090228","full_name":"softdevteam/vtable_bench","owner":"softdevteam","description":"Fat pointers vs. inner vtables experiment.","archived":false,"fork":false,"pushed_at":"2019-02-12T11:29:30.000Z","size":23,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-12-25T17:42:38.903Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/softdevteam.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2019-02-04T14:24:45.000Z","updated_at":"2022-10-30T03:59:45.000Z","dependencies_parsed_at":null,"dependency_job_id":"ddc8b287-e105-4644-8fb7-4f0afed05df0","html_url":"https://github.com/softdevteam/vtable_bench","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/softdevteam%2Fvtable_bench","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/softdevteam%2Fvtable_bench/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/softdevteam%2Fvtable_bench/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/softdevteam%2Fvtable_bench/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/softdevteam","download_url":"https://codeload.github.com/softdevteam/vtable_bench/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239217107,"owners_count":19601593,"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":[],"created_at":"2024-11-06T13:39:02.291Z","updated_at":"2025-02-17T00:44:16.069Z","avatar_url":"https://github.com/softdevteam.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# vtable_bench\n\nThis is a series of benchmarks designed to give some understanding of how\nperformance in Rust programs depending on whether the vtable pointer is stored\nalongside the normal pointer (a \"fat pointer\") or next to the object itself\n(\"inner vtable pointers\").\n\nYou can perform a run with default values as follows:\n\n```\n$ cargo build --release \u0026\u0026 cargo run --release --bin vtable_bench\n```\n\n\n# Why this is worth measuring\n\nTrait objects' vtables are passed around as fat pointers. If they're used\nrarely, this seems unlikely to make much performance difference either way.\nHowever, if we're expecting to have a reasonably large number of trait objects,\nit's not obvious if fat pointers (2 machine words) are a better trade-off vs.\nstoring the vtable pointer in the object itself (making pointers 1 machine\nword at the cost of an indirection to access the vtable).\n\nThese benchmarks are an attempt to start understanding the performance\ntrade-offs. They are highly simplistic, and inevitably only tell us about a\nsmall handful of possible performance points. They might be better than\nnothing, however.\n\nEach benchmark creates one or more trait objects, puts them in a vector, and\nthen iterates over that vector calling a method:\n\n* The `fat` benchmarks use fat pointers and the `innervpointer` benchmarks store\n  the vtable alongside the data itself (recreating fat pointers on an as-needed\n  basis).\n\n* The `multialias` benchmarks allocate a single box and multiply alias it;\n  non-`multialias` benchmarks allocate multiple boxes without aliasing.\n\n* The `no_read` benchmarks do not read from self (they return a fixed integer);\n  `with_read` benchmarks do read from self. This is trying to understand whether\n  bringing a trait object into cache by reading its vtable offsets the later\n  read.\n\nThe runner is fairly simplistic, but runs each benchmark in its own process\n(with 30 process executions and 100 in-process iterations), printing means and\n99% confidence intervals (calculated from the standard deviation).\n\n\n# Example results\n\n`vtable_bench` takes (optionally) 3 arguments:\n\n```\n$ cargo run --release --bin vtable_bench -- -h\nUsage: vtable_bench [-h] [\u003c#reps\u003e \u003c#iters\u003e \u003c#vec size\u003e]\n```\n\nFrom right to left (since it's easier to understand that way): the vector\nbeing iterated over will contain `vec size` elements; a `for` loop will\niterate over that vector `iters` times; and the benchmark will be\nexecuted from scratch `reps` times (each execution creating a fresh Unix\nprocess).\n\nHere are example runs (with irrelevant lines elided) with a gradually increasing\n`vec size` and a decreasing number of `iters` to keep the runs to a manageable\ntime and make comparisons easier:\n\n```\n$ cargo build --release\n$ cargo run --release --bin vtable_bench 30 10000 100000\nbench_fat_multialias_no_read: 1.628 +/- 0.0019\nbench_fat_multialias_with_read: 1.630 +/- 0.0030\nbench_fat_no_read: 1.627 +/- 0.0003\nbench_fat_with_read: 1.677 +/- 0.0045\nbench_innervpointer_multialias_no_read: 1.628 +/- 0.0011\nbench_innervpointer_multialias_with_read: 1.627 +/- 0.0002\nbench_innervpointer_no_read: 1.660 +/- 0.0032\nbench_innervpointer_with_read: 1.671 +/- 0.0023\n$ cargo run --release --bin vtable_bench 30 1000 1000000\nbench_fat_multialias_no_read: 1.709 +/- 0.0104\nbench_fat_multialias_with_read: 1.709 +/- 0.0099\nbench_fat_no_read: 1.708 +/- 0.0138\nbench_fat_with_read: 2.152 +/- 0.0103\nbench_innervpointer_multialias_no_read: 1.641 +/- 0.0007\nbench_innervpointer_multialias_with_read: 1.644 +/- 0.0115\nbench_innervpointer_no_read: 2.111 +/- 0.0054\nbench_innervpointer_with_read: 2.128 +/- 0.0090\n$ cargo run --release --bin vtable_bench 30 100 10000000\nbench_fat_multialias_no_read: 1.700 +/- 0.0012\nbench_fat_multialias_with_read: 1.707 +/- 0.0128\nbench_fat_no_read: 1.694 +/- 0.0014\nbench_fat_with_read: 2.182 +/- 0.0071\nbench_innervpointer_multialias_no_read: 1.666 +/- 0.0006\nbench_innervpointer_multialias_with_read: 1.681 +/- 0.0240\nbench_innervpointer_no_read: 2.129 +/- 0.0046\nbench_innervpointer_with_read: 2.152 +/- 0.0099\n$ cargo run --release --bin vtable_bench 30 10 100000000\nbench_fat_multialias_no_read: 1.708 +/- 0.0101\nbench_fat_multialias_with_read: 1.702 +/- 0.0038\nbench_fat_no_read: 1.705 +/- 0.0126\nbench_fat_with_read: 2.184 +/- 0.0046\nbench_innervpointer_multialias_no_read: 1.664 +/- 0.0081\nbench_innervpointer_multialias_with_read: 1.666 +/- 0.0101\nbench_innervpointer_no_read: 2.146 +/- 0.0138\nbench_innervpointer_with_read: 2.169 +/- 0.0125\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoftdevteam%2Fvtable_bench","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsoftdevteam%2Fvtable_bench","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoftdevteam%2Fvtable_bench/lists"}