{"id":13729661,"url":"https://github.com/tobspr/FastDynamicCast","last_synced_at":"2025-05-08T02:30:38.571Z","repository":{"id":84103672,"uuid":"76437365","full_name":"tobspr/FastDynamicCast","owner":"tobspr","description":"Fast dynamic cast in C++ for MSVC, outperforming the regular dynamic cast by up to 25 times","archived":false,"fork":false,"pushed_at":"2016-12-27T04:51:17.000Z","size":56,"stargazers_count":99,"open_issues_count":3,"forks_count":6,"subscribers_count":12,"default_branch":"master","last_synced_at":"2024-08-04T02:08:54.895Z","etag":null,"topics":[],"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/tobspr.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}},"created_at":"2016-12-14T07:54:57.000Z","updated_at":"2024-08-02T08:03:19.000Z","dependencies_parsed_at":"2024-01-07T16:31:37.681Z","dependency_job_id":"ea881ea5-b5ca-4637-afd2-fbb1996569c3","html_url":"https://github.com/tobspr/FastDynamicCast","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/tobspr%2FFastDynamicCast","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tobspr%2FFastDynamicCast/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tobspr%2FFastDynamicCast/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tobspr%2FFastDynamicCast/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tobspr","download_url":"https://codeload.github.com/tobspr/FastDynamicCast/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224689072,"owners_count":17353323,"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-08-03T02:01:03.568Z","updated_at":"2024-11-14T20:31:06.071Z","avatar_url":"https://github.com/tobspr.png","language":"C++","readme":"# Fast dynamic cast\n\nThis is a single header, dynamic cast implementation which outperforms the regular `dynamic_cast` by up to 25 times.\n\nWorks on MSVC 2013 or newer.\n\n# Performance\n\nAll performance tests ran on 2 Xeons E5-2623. I ran each iteration count multiple times, and took the average.\n\nThe solution used to measure the performance can be found in `dcast_performance`.\n\nNotice that all performance tests are more or less best-case scenarios which only perform dynamic_cast (see How it works).\n\n## Simple class hierarchy\n\n\u003cimg src=\"img/chart_simple.png\" /\u003e\n\n\n## Complex class hierarchy\n\n\u003cimg src=\"img/chart_complex.png\" /\u003e\n\n\n## Speedup vs regular dynamic_cast\n\n\u003cimg src=\"img/chart_speedup.png\" /\u003e\n\n\n# Usage\n\nCopy the `fast_dynamic_cast.h` header to your project, and change your `dynamic_cast` calls to `fast_dynamic_cast`, e.g.:\n\n```cpp\nA a;\nB\u0026 a_as_b = a;\nA\u0026 a_as_a = fast_dynamic_cast\u003cA\u0026\u003e(a_as_b);\n```\n\nThe syntax is identical to the regular dynamic cast. Theres also a `fast_dynamic_pointer_cast` available, which behaves identical to `std::dynamic_pointer_cast`.\n\nThe dynamic cast implementation only works on MSVC 2013 or newer. For all other compilers,\nit will fallback to the default dynamic cast.\n\nIf you want to use it in a multithreaded environment, change `DCAST_MULTITHREADED` to `1`.\n\n# How it works\n\nThe dynamic cast has two tasks to do:\n\n- Ensure the object is related and castable to the requested type\n- Move the pointer so it points to the requested class block.\n\nThe fast dynamic cast is built on top on the regular dynamic cast.\nIt improves performance by observing that, after we ensured the class is convertible,\nwe can cache the offset required to shift the pointer.\n\nFor example, assuming we have a `class A` and `B`, whereas `B` derives from `A`, and we want to cast an `A pointer` to a `B pointer`.\nThe first time this cast is invoked, the fast dynamic cast uses the regular dynamic cast to\nretrieve the casted pointer.\n\nLets say the dynamic cast shifted the A pointer by `+8`, then the fast dynamic cast stores this offset.\nThe next time the cast is invoked, the incoming pointer is just shifted by `+8` and returned, which is much faster\nand avoids the `dynamic_cast` call.\n\nHowever, there are two cases where this approach cannot be used:\n\n- The pointer passed in is not actually castable\n- The pointer is already shifted\n\nCase 2 can occur, if we for example call `fast_dynamic_cast\u003cA*\u003e(B*)`, but the passed pointer\npoints to a derived `C` class (whereas `C` derives from `B`). This is a problem, since the\noffset from `C -\u003e A` is different than the offset from `B -\u003e A`.\n\nThe fast dynamic cast solves both problems by additionally also storing the VTable pointer in the cache.\nWhen an object is casted, the fast dynamic cast only detects a cache hit if the vtable\npointer matches, and if not, performs the regular dynamic cast.\n\nIn theory, casting many different objects to the same superclass would then be even less performant\nthan the regular dynamic cast. However, in practice, the cache usage is over 95%, and thus the fast dynamic cast is up to a order\nof magnitude faster than the regular dynamic cast. \n\n","funding_links":[],"categories":["C++"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftobspr%2FFastDynamicCast","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftobspr%2FFastDynamicCast","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftobspr%2FFastDynamicCast/lists"}