{"id":26029082,"url":"https://github.com/lofcz/fastcloner","last_synced_at":"2026-04-02T17:06:30.766Z","repository":{"id":271398373,"uuid":"913311293","full_name":"lofcz/FastCloner","owner":"lofcz","description":"The fastest deep cloning library for .NET – zero-config, works out of the box.","archived":false,"fork":false,"pushed_at":"2026-03-28T22:50:39.000Z","size":1653,"stargazers_count":342,"open_issues_count":1,"forks_count":11,"subscribers_count":4,"default_branch":"next","last_synced_at":"2026-03-28T23:03:08.262Z","etag":null,"topics":["aot","c-sharp","cloner","copier","csharp-sourcegenerator","deep-clone","deep-cloning","deep-copy","deepclone","deepcopy","dotnet","dotnet-core","duplication","roslyn","source-gen","source-generator","sourcegenerator"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"adimosh/DeepCloner","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lofcz.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-01-07T12:46:49.000Z","updated_at":"2026-03-28T22:50:42.000Z","dependencies_parsed_at":"2025-01-07T22:33:09.388Z","dependency_job_id":"0d7bce80-310b-4b47-8e00-946a8068aac0","html_url":"https://github.com/lofcz/FastCloner","commit_stats":null,"previous_names":["lofcz/deepcloner","lofcz/fastcloner"],"tags_count":41,"template":false,"template_full_name":null,"purl":"pkg:github/lofcz/FastCloner","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lofcz%2FFastCloner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lofcz%2FFastCloner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lofcz%2FFastCloner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lofcz%2FFastCloner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lofcz","download_url":"https://codeload.github.com/lofcz/FastCloner/tar.gz/refs/heads/next","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lofcz%2FFastCloner/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31311132,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T12:59:32.332Z","status":"ssl_error","status_checked_at":"2026-04-02T12:54:48.875Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["aot","c-sharp","cloner","copier","csharp-sourcegenerator","deep-clone","deep-cloning","deep-copy","deepclone","deepcopy","dotnet","dotnet-core","duplication","roslyn","source-gen","source-generator","sourcegenerator"],"created_at":"2025-03-06T17:30:05.665Z","updated_at":"2026-04-02T17:06:30.755Z","avatar_url":"https://github.com/lofcz.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003cimg width=\"512\" alt=\"FastCloner\" src=\"https://github.com/user-attachments/assets/9b6b82a3-892a-4607-9c57-6580ca856a37\" /\u003e\n\n# FastCloner\n\n**The fastest and most reliable .NET deep cloning library.**    \n\n[![FastCloner](https://shields.io/nuget/v/FastCloner?v=304\u0026icon=nuget\u0026label=FastCloner)](https://www.nuget.org/packages/FastCloner)\n[![FastCloner](https://shields.io/nuget/v/FastCloner.SourceGenerator?v=304\u0026icon=nuget\u0026label=FastCloner.SourceGenerator)](https://www.nuget.org/packages/FastCloner.SourceGenerator)\n[![License:MIT](https://img.shields.io/badge/License-MIT-34D058.svg)](https://opensource.org/license/mit)\n\nFastCloner is a zero-dependency deep cloning library for .NET, from \u003ccode\u003e.NET 4.6\u003c/code\u003e to \u003ccode\u003e.NET 10+\u003c/code\u003e. It combines source generation with optimized reflection fallback, so deep cloning _just works_.\n \n\u003c/div\u003e\n\n## ✨ Features\n\n- **The Fastest** - [Benchmarked](https://github.com/lofcz/FastCloner?tab=readme-ov-file#performance) to beat all other libraries with [third-party](https://github.com/FoundatioFx/Foundatio/pull/469#issuecomment-4013424812) [independent](https://github.com/AnderssonPeter/Dolly?tab=readme-ov-file#benchmarks) [benchmarks](https://github.com/arika0093/IDeepCloneable?tab=readme-ov-file#performance) verifying the performance. **300x** speed-up vs `Newtonsoft.Json` and **160x** vs `System.Text.Json`\n- **The Most Correct** - Built for the cases clone libraries get wrong: polymorphism, circular/shared references, readonly and immutable members, deep graphs, delegates, events, collections... Backed by [800+ tests](https://github.com/lofcz/FastCloner/tree/next/FastCloner.Tests), with documented [limitations](https://github.com/lofcz/FastCloner?tab=readme-ov-file#limitations)\n- **Hybrid AOT** - Uses generated clone code wherever possible, with targeted fallback to the runtime engine only where safety or correctness requires it\n- **Automatic type discovery** - The generator follows usages of generic and abstract types and emits concrete clone paths automatically\n- **Embeddable** - No dependencies outside the standard library. Source generator and reflection parts can be installed independently\n- **Precise control** - Override clone behavior per type or member with `Clone`, `Reference`, `Shallow`, or `Ignore`, at compile time or runtime\n- **Selective tracking** - FastCloner avoids identity and cycle-tracking overhead by default, but enables it when graph shape or `[FastClonerPreserveIdentity]` requires it\n- **Easy Integration** - `FastDeepClone()` for AOT cloning, `DeepClone()` for reflection cloning. FastCloner respects standard .NET attributes like `[NonSerialized]`, so you can adopt it without depending on library-specific annotations\n- **Production Ready** - Used by projects like [Foundatio](https://github.com/FoundatioFx/Foundatio), [Jobbr](https://jobbr.readthedocs.io/en/latest), [TarkovSP](https://sp-tarkov.com), [SnapX](https://github.com/SnapXL/SnapX), and [WinPaletter](https://github.com/Abdelrhman-AK/WinPaletter), with over [300K downloads on NuGet](https://www.nuget.org/packages/fastCloner#usedby-body-tab)\n## Getting Started\n\nInstall the package via NuGet:\n\n```powershell\ndotnet add package FastCloner # Reflection\ndotnet add package FastCloner.SourceGenerator # AOT\n```\n\n### Clone via Reflection\n\n```csharp\nusing FastCloner.Code;\nvar clone = FastCloner.FastCloner.DeepClone(new { Hello = \"world\", MyList = new List\u003cint\u003e { 1 } });\n```\n\nFor convenience, add the following method to your project. We intentionally don't ship this extension to make switching from/to FastCloner easier:\n\n```cs\n[return: NotNullIfNotNull(nameof(obj))]\npublic static T? DeepClone\u003cT\u003e(this T? obj)\n{\n    return FastCloner.FastCloner.DeepClone(obj);\n}\n```\n\n### Clone via Source Generator\n\n```cs\n[FastClonerClonable]\npublic class GenericClass\u003cT\u003e\n{\n    public T Value { get; set; }\n}\n\npublic class MyClass\n{\n    public string StrVal { get; set; }\n}\n\n// [FastClonerClonable] is only required on types where you call .FastDeepClone()\nvar original = new GenericClass\u003cList\u003cMyClass\u003e\u003e { Value = new List\u003cMyClass\u003e { new MyClass { StrVal = \"hello world\" } } };\nvar clone = original.FastDeepClone();\n```\n\n## Advanced Usage\n\n### Customizing Clone Behavior\n\nFastCloner supports behavior attributes that control how types and members are cloned:\n\n| Behavior | Effect |\n|----------|--------|\n| `Clone` | Deep recursive copy |\n| `Reference` | Return original instance unchanged |\n| `Shallow` | `MemberwiseClone` without recursion |\n| `Ignore` | Return `default` |\n\n#### Compile-time (Attributes)\n\nApply attributes to **types** or **members**. Member-level attributes override type-level:\n\n```csharp\n[FastClonerReference]  // Type-level: all usages preserve reference\npublic class SharedService { }\n\npublic class MyClass\n{\n    public SharedService Svc { get; set; }      // Uses type-level → Reference\n    \n    [FastClonerBehavior(CloneBehavior.Clone)]   // Member-level override → Clone\n    public SharedService ClonedSvc { get; set; }\n    \n    [FastClonerIgnore]                          // → null/default\n    public CancellationToken Token { get; set; }\n    \n    [FastClonerShallow]                         // → Reference copied directly\n    public ParentNode Parent { get; set; }\n}\n```\n\nShorthand attributes: `[FastClonerIgnore]`, `[FastClonerShallow]`, `[FastClonerReference]`  \nExplicit: `[FastClonerBehavior(CloneBehavior.X)]`\n\n#### Runtime (Reflection only)\n\nConfigure type behavior dynamically. Runtime settings are checked **before** attributes:\n\n```csharp\nFastCloner.FastCloner.SetTypeBehavior\u003cMySingleton\u003e(CloneBehavior.Reference);\nFastCloner.FastCloner.ClearTypeBehavior\u003cMySingleton\u003e();    // Reset one\nFastCloner.FastCloner.ClearAllTypeBehaviors();             // Reset all\n```\n\n\u003e **Note**: Changing runtime behavior invalidates the cache. Try to configure once at startup, or use compile-time attributes when possible.\n\n#### Precedence (highest to lowest)\n\n1. Runtime `SetTypeBehavior\u003cT\u003e()` \n2. Member-level attribute\n3. Type-level attribute on member's type\n4. Default behavior\n\n### Cache Management\n\n```csharp\nFastCloner.FastCloner.ClearCache();  // Free memory from reflection cache\n```\n\n\n### Generic Classes and Abstract Types\n\nThe source generator automatically discovers which concrete types your generic classes and abstract hierarchies are used with:\n\n**Generic types** - The generator scans your codebase for usages like `MyClass\u003cint\u003e` or `MyClass\u003cCustomer\u003e` and generates specialized cloning code:\n\n```cs\n[FastClonerClonable]\npublic class Container\u003cT\u003e\n{\n    public T Value { get; set; }\n}\n\n// Source generator finds this usage and generates cloning code for Container\u003cint\u003e\nvar container = new Container\u003cint\u003e { Value = 42 };\nvar clone = container.FastDeepClone();\n```\n\n**Abstract classes** - The generator automatically finds all concrete derived types in your codebase:\n\n```cs\n[FastClonerClonable]\npublic abstract class Animal\n{\n    public string Name { get; set; }\n}\n\npublic class Dog : Animal\n{\n    public string Breed { get; set; }\n}\n\npublic class Cat : Animal\n{\n    public bool IsIndoor { get; set; }\n}\n\n// Cloning via the abstract type works - the generator discovered Dog and Cat\nAnimal pet = new Dog { Name = \"Buddy\", Breed = \"Labrador\" };\nAnimal clone = pet.FastDeepClone(); // Returns a cloned Dog\n```\n\n### Explicitly Including Types\n\nWhen a type is only used dynamically (not visible at compile time), use `[FastClonerInclude]` to ensure the generator creates cloning code for it:\n\n```cs\n[FastClonerClonable]\n[FastClonerInclude(typeof(Customer), typeof(Order))] // Include types used dynamically\npublic class Wrapper\u003cT\u003e\n{\n    public T Value { get; set; }\n}\n```\n\nFor abstract classes, you can also use `[FastClonerInclude]` to add derived types that aren't in your codebase (e.g., from external assemblies):\n\n```cs\n[FastClonerClonable]\n[FastClonerInclude(typeof(ExternalPlugin))] // Add external derived types\npublic abstract class Plugin\n{\n    public string Name { get; set; }\n}\n```\n\n### Custom Cloning Context\n\nFor advanced scenarios, create a custom cloning context to explicitly register types you want to clone. This is useful when you need a centralized cloning entry point or want to clone types from external assemblies:\n\n```cs\npublic class Customer\n{\n    public string Name { get; set; }\n    public Address Address { get; set; }\n}\n\npublic class Address\n{\n    public string City { get; set; }\n}\n\n// Create a context and register types to clone\n[FastClonerRegister(typeof(Customer), typeof(Address))]\npublic partial class MyCloningContext : FastClonerContext { }\n```\n\nUsing the context:\n```cs\nMyCloningContext ctx = new MyCloningContext();\n\n// Clone with compile-time type safety\nCustomer clone = ctx.Clone(original);\n\n// Check if a type is handled by this context\nbool handled = ctx.IsHandled(typeof(Customer)); // true\n\n// Try to clone (returns false for unregistered types)\nif (ctx.TryClone(obj, out var cloned))\n{\n    // Successfully cloned\n}\n```\n\n### Nullability Trust\n\nThe generator can be instructed to fully trust nullability annotations. When `[FastClonerTrustNullability]` attribute is applied, FastCloner will skip null checks for non-nullable reference types (e.g., `string` vs `string?`), assuming the contract is valid.\n\n```csharp\n[FastClonerClonable]\n[FastClonerTrustNullability] // Skip null checks for non-nullable members\npublic class HighPerformanceDto\n{\n    public string Id { get; set; } // No null check generated\n    public string? Details { get; set; } // Null check still generated\n}\n```\n\nThis eliminates branching and improves performance slightly. If a non-nullable property is actually null at runtime, this may result in a `NullReferenceException` in the generated code.\n\n### Safe Handles\n\nWhen you have a struct that acts as a handle to internal state or a singleton (where identity matters), use `[FastClonerSafeHandle]`. This tells FastCloner to shallow-copy the readonly fields instead of deep-cloning them, preserving the original internal references.\n\n```csharp\n[FastClonerSafeHandle]\npublic struct MyHandle\n{\n    private readonly object _internalState; // Preserved (shared), not deep cloned\n    public int Value; // Cloned normally\n}\n```\n\nThis is the default behavior for system types like `System.Net.Http.Headers.HeaderDescriptor` to prevent breaking internal framework logic. Use this attribute if your custom structs behave similarly.\n\n### Identity Preservation\n\nBy default, FastCloner prioritizes performance by not tracking object identity during cloning. This means if the same object instance appears multiple times in your graph, each reference becomes a separate clone.\n\nFor scenarios where you need to preserve object identity (e.g., shared references should remain shared in the clone), use `[FastClonerPreserveIdentity]`:\n\n```csharp\n[FastClonerClonable]\n[FastClonerPreserveIdentity] // Enable identity tracking for this type\npublic class Document\n{\n    public User Author { get; set; }\n    public User LastEditor { get; set; } // May reference the same User as Author\n}\n\nvar doc = new Document { Author = user, LastEditor = user };\nvar clone = doc.FastDeepClone();\n// clone.Author == clone.LastEditor (same cloned instance)\n```\n\nThe attribute can be applied at type level or member level:\n\n```csharp\n[FastClonerClonable]\npublic class Container\n{\n    // Only this member tracks identity\n    [FastClonerPreserveIdentity]\n    public List\u003cNode\u003e Nodes { get; set; }\n    \n    // This member clones without identity tracking (faster)\n    public List\u003cItem\u003e Items { get; set; }\n}\n```\n\nYou can also explicitly disable identity preservation for a member when the type has it enabled:\n\n```csharp\n[FastClonerClonable]\n[FastClonerPreserveIdentity]\npublic class Graph\n{\n    public Node Root { get; set; }\n    \n    [FastClonerPreserveIdentity(false)] // Opt out for this member\n    public List\u003cstring\u003e Labels { get; set; }\n}\n```\n\n\u003e **Note**: Identity preservation adds overhead for tracking seen objects. Circular references are always detected regardless of this setting.\n\n## Limitations\n\n- Cloning unmanaged resources, such as `IntPtr`s may result in side-effects, as there is no metadata for the length of buffers such pointers often point to.\n- `ReadOnly` and `Immutable` collections are tested to behave well if they follow basic conventions.\n- With reflection, cloning deeply nested objects switches from recursion to iterative approach on the fly. The threshold for this can be configured by changing `FastCloner.MaxRecursionDepth`, iterative approach is marginally slower.\n\n## Performance\n\nFastCloner is the _fastest_ deep cloning library across both reflection-based and AOT workloads. It was benchmarked against every library capable of cloning objects I've been able to find:\n```md\nBenchmarkDotNet v0.15.8, Windows 11 (10.0.26220.7271)\nIntel Core i7-8700 CPU 3.20GHz (Max: 3.19GHz) (Coffee Lake), 1 CPU, 12 logical and 6 physical cores\n.NET SDK 10.0.100\n\n| Method             | Mean        | Error      | StdDev     | Median      | Ratio  | RatioSD | Rank | Gen0   | Gen1   | Allocated | Alloc Ratio |\n|------------------- |------------:|-----------:|-----------:|------------:|-------:|--------:|-----:|-------:|-------:|----------:|------------:|\n| FastCloner         |    10.25 ns |   0.219 ns |   0.183 ns |    10.24 ns |   1.00 |    0.02 |    1 | 0.0115 |      - |      72 B |        1.00 |\n| DeepCopier         |    23.37 ns |   0.448 ns |   0.582 ns |    23.29 ns |   2.28 |    0.07 |    2 | 0.0115 |      - |      72 B |        1.00 |\n| DeepCopy           |    40.56 ns |   3.589 ns |  10.583 ns |    43.56 ns |   3.96 |    1.03 |    3 | 0.0115 |      - |      72 B |        1.00 |\n| DeepCopyExpression |   126.05 ns |   3.355 ns |   9.892 ns |   129.32 ns |  12.30 |    0.98 |    4 | 0.0356 |      - |     224 B |        3.11 |\n| AutoMapper         |   135.07 ns |   6.097 ns |  17.976 ns |   143.16 ns |  13.18 |    1.76 |    5 | 0.0114 |      - |      72 B |        1.00 |\n| DeepCloner         |   261.42 ns |  14.113 ns |  41.614 ns |   282.99 ns |  25.51 |    4.06 |    6 | 0.0367 |      - |     232 B |        3.22 |\n| ObjectCloner       |   336.89 ns |  14.249 ns |  42.012 ns |   355.28 ns |  32.87 |    4.12 |    7 | 0.0534 |      - |     336 B |        4.67 |\n| MessagePack        |   499.71 ns |  20.831 ns |  61.420 ns |   524.63 ns |  48.75 |    6.02 |    8 | 0.0315 |      - |     200 B |        2.78 |\n| ProtobufNet        |   898.60 ns |  34.925 ns | 102.978 ns |   934.13 ns |  87.67 |   10.11 |    9 | 0.0782 |      - |     496 B |        6.89 |\n| NClone             |   904.75 ns |  33.559 ns |  98.949 ns |   919.05 ns |  88.27 |    9.73 |    9 | 0.1488 |      - |     936 B |       13.00 |\n| SystemTextJson     | 1,687.39 ns |  70.341 ns | 201.821 ns | 1,766.14 ns | 164.63 |   19.79 |   10 | 0.1755 |      - |    1120 B |       15.56 |\n| NewtonsoftJson     | 3,147.66 ns | 109.097 ns | 321.676 ns | 3,269.96 ns | 307.10 |   31.67 |   11 | 0.7286 | 0.0038 |    4592 B |       63.78 |\n| FastDeepCloner     | 3,970.90 ns | 155.503 ns | 458.505 ns | 4,128.09 ns | 387.41 |   45.01 |   12 | 0.2060 |      - |    1304 B |       18.11 |\n| AnyCloneBenchmark  | 5,102.40 ns | 239.089 ns | 704.959 ns | 5,370.93 ns | 497.81 |   68.98 |   13 | 0.9003 |      - |    5656 B |       78.56 |\n```\n\nYou can run the benchmark [locally](https://github.com/lofcz/FastCloner/blob/next/src/FastCloner.Benchmark/BenchMinimal.cs) to verify the results.\n\n### Build Times \u0026 IDE Performance\n\nThe source generator is designed to work with Roslyn's incremental model. It uses `ForAttributeWithMetadataName`, turns Roslyn symbols into stable `TypeModel` / `MemberModel` records early, and keeps `ISymbol`, syntax nodes, and `Compilation` out of the output pipeline.\n\n- **Incremental pipeline** - Type analysis happens during the transform step, so codegen re-runs only when decorated types or relevant usage data changes.\n- **Stable models** - `TypeModel` and `MemberModel` hold precomputed data instead of Roslyn symbols, which keeps incremental caching effective across edits.\n- **No `CompilationProvider` in output** - The output pipeline intentionally avoids it to reduce broad invalidation and unnecessary regeneration.\n- **Deterministic collection equality** - `EquatableArray` is used so generator model collections compare cleanly in the incremental pipeline.\n- **Inlining of one-off helpers** - Helpers used once are inlined to keep generated clone paths direct.\n\n## Internalization\n\nFor consumers who wish to embed FastCloner directly without adding a dependency, use the [internalization builder project](https://github.com/lofcz/FastCloner/tree/next/src/FastCloner.Internalization.Builder).\n\nExample command:\n\n```bash\ndotnet run --project src/FastCloner.Internalization.Builder/FastCloner.Internalization.Builder.csproj -- \\\n  --root-namespace MyLibrary.FastCloner \\\n  --output ../MyLibrary/FastCloner \\\n  --preprocessor \"MODERN=true;\" \\\n  --fqn all \\\n  --visibility internal \\\n  --public-api none \\\n  --runtime-only true \\\n  --self-check\n```\n\nCLI options:\n\n- `--root-namespace \u003cns\u003e`: Rewrites `FastCloner` namespaces to your target root namespace.\n- `--preprocessor \u003cSYMBOL=VALUE;...\u003e`: Per-symbol preprocessor transformation input.\n  - `VALUE=true|false` is recognized as boolean and enables full condition resolution/removal where possible.\n  - any other value is used as direct replacement in `#if` expressions (e.g., `SOMETHING=random_text`).\n  - This lets the builder resolve `#if` branches ahead of time and emit target-specific code.\n- `--fqn \u003cprefix1|prefix2|...\u003e`: Fully qualifies matching external metadata types in generated code.\n  - Use `all` to qualify all external metadata types.\n  - Use prefixes such as `System|System.Collections` to limit qualification to selected namespaces.\n  - This is useful when embedding FastCloner into a project that already defines colliding namespaces or type names.\n- `--implicit-usings \u003cns1;ns2;...\u003e`: Namespaces the target project already imports implicitly.  \n  Generated global usings for these namespaces are omitted.  \n  Default is empty, so generated code carries explicit usings.\n- `--visibility \u003cpublic|internal\u003e`: Top-level visibility rewrite policy.\n- `--public-api \u003cnone|fastcloner|extensions|behaviors|all\u003e`: Keeps selected public surface when `--visibility internal` is used.\n- `--runtime-only \u003ctrue|false\u003e`: Includes only runtime clone engine files.\n- `--dry-run`: Prints planned output files and transform stats without writing.\n- `--self-check`: Compiles generated source tree and reports compile errors.\n\n## Contributing\n\nIf you are looking to add new functionality, please open an issue first to verify your intent is aligned with the scope of the project. The library is covered by over [800 tests](https://github.com/lofcz/FastCloner/tree/next/src/FastCloner.Tests), please run them against your work before proposing changes. Tests run in parallel to verify thread-safety of the library (with targeted exceptions). Run `dotnet test` from the cloned repo root. We also run benchmark regression analysis on every pull request to `next`; if a change causes a measurable performance regression, the PR should clearly justify that trade-off. When reporting issues, providing a minimal reproduction we can plug in as a new test greatly reduces turnaround time. We use [TUnit](https://github.com/thomhurst/TUnit) for testing.\n\nEach PR gets an updated benchmark report comment from `github-actions`, so you can spot regressions early and iterate before merge.\n\n\u003cdetails\u003e\n\u003csummary\u003eExample benchmark report\u003c/summary\u003e\n\n| Status | Benchmark | Delta Time | Delta Alloc |\n|---|---|---|---|\n| 🟢 | DynamicWithArray | -15% faster | ~same |\n| ⚪ | DynamicWithDictionary | +5% slower | ~same |\n| ⚪ | DynamicWithNestedObject | ~same | ~same |\n| ⚪ | FileSpec | -4% faster | ~same |\n| 🟢 | LargeEventDocument_10MB | -7% faster | ~same |\n| ⚪ | LargeLogBatch_10MB | ~same | ~same |\n| ⚪ | MediumNestedObject | ~same | ~same |\n| ⚪ | ObjectDictionary_50 | ~same | ~same |\n| ⚪ | ObjectList_100 | -2% faster | ~same |\n| 🟢 | SmallObject | -6% faster | ~same |\n| ⚪ | SmallObjectWithCollections | -2% faster | ~same |\n| ⚪ | StringArray_1000 | ~same | ~same |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eTests Troubleshooting\u003c/summary\u003e\n\nRider: automatic tests discovery\n  - Temporarily disable VSTest adapters support (`Build, Execution, Deployment \u003e Unit Testing \u003e VSTest`)\n  - Enable Testing Platform support (`Build, Execution, Deployment \u003e Unit Testing \u003e Testing Platform`)\n  - Re-enable VSTest adapters support\n  - Rebuild / refresh the test explorer\n\n\u003c/details\u003e\n\n## License\n\nThis library is licensed under the [MIT](https://github.com/lofcz/FastCloner/blob/next/LICENSE) license. 💜\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flofcz%2Ffastcloner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flofcz%2Ffastcloner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flofcz%2Ffastcloner/lists"}