{"id":15011668,"url":"https://github.com/ffhighwind/fasterflect","last_synced_at":"2025-10-06T05:31:13.367Z","repository":{"id":65413993,"uuid":"177469553","full_name":"ffhighwind/Fasterflect","owner":"ffhighwind","description":".NET Reflection Made Fast and Simple ⛺","archived":false,"fork":true,"pushed_at":"2021-03-16T07:58:51.000Z","size":2115,"stargazers_count":28,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-18T02:53:59.037Z","etag":null,"topics":["benchmarks","fast","il","intermediate-language","nuget","nuget-package","performance","reflection"],"latest_commit_sha":null,"homepage":"https://www.nuget.org/packages/Fasterflect.Reflect/","language":"C#","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"buunguyen/fasterflect","license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ffhighwind.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}},"created_at":"2019-03-24T21:08:05.000Z","updated_at":"2024-12-04T14:37:15.000Z","dependencies_parsed_at":"2023-01-23T10:55:06.931Z","dependency_job_id":null,"html_url":"https://github.com/ffhighwind/Fasterflect","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/ffhighwind%2FFasterflect","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ffhighwind%2FFasterflect/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ffhighwind%2FFasterflect/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ffhighwind%2FFasterflect/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ffhighwind","download_url":"https://codeload.github.com/ffhighwind/Fasterflect/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235503734,"owners_count":19000700,"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":["benchmarks","fast","il","intermediate-language","nuget","nuget-package","performance","reflection"],"created_at":"2024-09-24T19:41:25.124Z","updated_at":"2025-10-06T05:31:08.022Z","avatar_url":"https://github.com/ffhighwind.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Introduction\n\n[Nuget: Fasterflect.Reflect](https://www.nuget.org/packages/Fasterflect.Reflect/)\n\nThis framework is based on [Fasterflect](https://github.com/buunguyen/Fasterflect), which was originally developed by Buu Nguyen and Morten Mertner. The extension methods in this version have been moved to a separate namespace to ensure that they do not clutter intellisense and auto-complete. Most of the methods been moved to Reflect and ReflectLookup static classes in order to achieve this. It also includes two new features: MultiSetter and DataReaderFactory.\n\n## Benchmarks\n\nFasterflect is 50x faster than .NET reflection, 8x faster than FastMember, and 2-10x slower than direct access. Note also that Fasterflect only uses *objects* as arguments and return types. This slows down the methods because data needs to be boxed and unboxed. However, this is usually the only time that reflection is useful. If you know the generic types at compile time then you can probably use an interface instead of reflection.\n\n|                         Property Getters |      Median |   Ratio |\n|----------------------------------------- |------------:|--------:|\n| Direct Access                            | 0.059 ns   | 0.02 |\n| Delegate.CreateDelegate (T,string)       | 1.896 ns   | 0.60 |\n| Fasterflect (object, object)             | **3.139 ns** | **1.00** |\n| Magnum - Expression.Compile (object, object) | 10.806 ns | 3.44 |\n| Sigil.ILEmit (T, string)                 | 12.765 ns  | 4.07 |\n| Sigil.ILEmit (object, object)            | 13.906 ns   | 4.43 |\n| FastMember (object, object)              | 31.356 ns  | 9.99 |\n| MethodInfo.Invoke\t                   | 126.890 ns | 40.43 |\n| PropertyInfo                             | 134.323 ns  | 42.80 |\n| PropertyInfo - uncached                  | 194.313 ns | 61.91 |\n| Delegate.DynamicInvoke                   | 714.374 ns | 227.60 |\n\n|                           Property Setters |     Median |  Ratio |\n|------------------------------------------- |-----------:|-------:|\n| Direct Access\t                             | 1.266 ns\t  | 0.33 |\n| Delegate.CreateDelegate (T, string)\t     | 3.048 ns\t  | 0.79 |\n| Sigil.ILEmit (T, string)\t             | 2.987 ns   | 0.78 |\n| Sigil.ILEmit (object, object)              | 3.735 ns   | 0.97 |\n| Fasterflect (object, object)               | **3.838 ns** | **1.00** |\n| Magnum - Expression.Compile (object, object) | 10.626 ns | 2.77 |\n| FastMember (object, object)                | 33.402 ns | 8.70 |\n| MethodInfo.Invoke                          | 196.676 ns | 51.24 |\n| PropertyInfo                               | 202.662 ns | 52.80 |\n| PropertyInfo - uncached                    | 265.131 ns | 69.08 |\n| Delegate.DynamicInvoke                     | 795.812 ns | 207.35 |\n\n\n[Other Benchmarks](https://github.com/ffhighwind/Fasterflect/wiki/Benchmarks)\n\n## Example\n\n```csharp\nusing System;\nusing Fasterflect;\n\nnamespace FasterflectExample\n{\npublic class Person\n{\n\tpublic Person(string name, int age)\n\t{\n\t\tName = name;\n\t\tAge = age;\n\t}\n\tpublic string Name { get; set; }\n\tpublic int Age;\n}\n\npublic class Program\n{\n\tpublic static void Main(string[] args)\n\t{\n\t\tConstructorInvoker ctor = Reflect.Constructor(typeof(Person), typeof(string), typeof(int));\n\t\tMemberGetter getName = Reflect.Getter(typeof(Person), \"Name\");\n\t\tMemberGetter getAge = Reflect.FieldGetter(typeof(Person), \"Age\");\n\t\tMemberSetter setAge = Reflect.Setter(typeof(Person), \"Age\");\n\t\tMultiSetter setBoth = Reflect.MultiSetter(typeof(Person), \"Age\", \"Name\");\n\n\t\tPerson person = (Person) ctor(\"John Doe\", 21);\n\t\tsetAge(person, 30);\n\t\tConsole.WriteLine(getName(person));\n\t\tConsole.WriteLine(getAge(person));\n\t\tsetBoth(person, 35, \"John Wick\");\n\t\tConsole.WriteLine(getName(person));\n\t\tConsole.WriteLine(getAge(person));\n\t\tConsole.ReadLine();\n\n\t\t// Output:\n\t\t// John Doe\n\t\t// 30\n\t\t// John Wick\n\t\t// 35\n\t}\n}\n}\n\n```\n\n## [Reflect](https://github.com/ffhighwind/fasterflect/blob/master/Fasterflect/Reflect.cs)\n\nReflect is the static factory for all reflection-based delegates. Every delegate that is generated is stored in a temporary cache using a [WeakReference](https://docs.microsoft.com/en-us/dotnet/api/system.weakreference?view=netframework-4.8). This allows delegates to be garbage collected but also ensures that you do cannot waste memory by creating multiple instances of the same delegate.\n\n| Method | Description |\n| --- | --- |\n| Reflect.Constructor() | ConstructorInfo |\n| Reflect.Getter() | MemberInfo (PropertyInfo or FieldInfo) | \n| Reflect.PropertyGetter() | PropertyInfo |\n| Reflect.FieldGetter() | FieldInfo |\n| Reflect.Setter() | MemberInfo (PropertyInfo or FieldInfo) |\n| Reflect.PropertySetter() | PropertyInfo |\n| Reflect.FieldSetter() | FieldInfo |\n| Reflect.MultiSetter() | Sets multiple properties/fields without using a loop. |\n| Reflect.Method() | MethodInfo |\n| Reflect.Mapper() | Maps the properties/fields of one type onto another type. This can be used as a shallow copy method if both types are the same. |\n| Reflect.IndexerGetter() | value = object[index1, index2] |\n| Reflect.IndexerSetter() | object[index1, index2] = value |\n| Reflect.ArrayGetter() | value = array[index] |\n| Reflect.ArraySetter() | array[index] = value |\n| Reflect.DeepClone\u003cT\u003e() | Creates a deep clone of an object. |\n| Reflect.ShallowClone\u003cT\u003e() | Creates a shallow clone of an object using MemberwiseClone. This can potentially throw an security exception because it requires accessing a protected method. |\n\n## [ReflectLookup](https://github.com/ffhighwind/fasterflect/blob/master/Fasterflect/ReflectLookup.cs)\n\nThis allows searching for reflection based objects using either FasterflectFlags or BindingFlags. This is up to 2x slower than .NET reflection, but it allows partial matching (string.Contains).\n\n## ValueTypes/Structs\n\nValue types must be wrapped with a [ValueTypeHolder](https://github.com/ffhighwind/Fasterflect/blob/master/Fasterflect/ValueTypeHolder.cs) to work with the Fasterflect delegates. This could have been prevented if I made the first argument of every delegate a ref. I have decided against this because value types are not supposed to be passed by reference and forcing the user to type ref for every call is tedious and it would reduce the performance for reference types.\n\n```csharp\nusing System;\nusing Fasterflect;\n\nnamespace FasterflectExampleStruct\n{\npublic struct Animal\n{\n\tpublic Animal(string name, int age)\n\t{\n\t\tName = name;\n\t\tAge = age;\n\t}\n\tpublic string Name { get; set; }\n\tpublic int Age;\n};\n\npublic static class Program\n{\n\tpublic static void Main(string[] args)\n\t{\n\t\tConstructorInvoker ctor = Reflect.Constructor(typeof(Animal), typeof(string), typeof(int));\n\t\tMemberGetter getName = Reflect.Getter(typeof(Animal), \"Name\");\n\t\tMemberGetter getAge = Reflect.FieldGetter(typeof(Animal), \"Age\");\n\t\tMemberSetter setAge = Reflect.Setter(typeof(Animal), \"Age\");\n\t\tMultiSetter setBoth = Reflect.MultiSetter(typeof(Animal), \"Age\", \"Name\");\n\n\t\tAnimal animal = (Animal)ctor(\"Charlie\", 5);\n\t\tValueTypeHolder holder = new ValueTypeHolder(animal); // IMPORTANT!\n\t\tsetAge(holder, 8);\n\t\tConsole.WriteLine(getName(holder));\n\t\tConsole.WriteLine(getAge(holder));\n\t\tsetBoth(holder, 10, \"Buster\");\n\t\tConsole.WriteLine(getName(holder));\n\t\tConsole.WriteLine(getAge(holder));\n\t\tConsole.ReadLine();\n\n\t\t// Output:\n\t\t// Charlie\n\t\t// 8\n\t\t// Buster\n\t\t// 10\n\t}\n}\n}\n```\n\n## [DataReaderFactory](https://github.com/ffhighwind/Fasterflect/blob/master/Fasterflect/DataReaderFactory.cs)\n\nThis is based on FastMember's [ObjectReader](https://github.com/mgravell/fast-member/blob/master/FastMember/ObjectReader.cs). It can be used with SqlBulkCopy which is up to 100x faster than a loop of individual database inserts. It can also be used as a parameter for DataTable.Load() to convert a list of objects to a DataTable.\n\n## [Emitter.EmitHelper](https://github.com/ffhighwind/Fasterflect/blob/master/Fasterflect/Emitter/EmitHelper.cs)\n\nThis is a wrapper around [System.Reflection.Emit.IlGenerator](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.ilgenerator?view=netframework-4.8) that is easier to read and simple to use.\n\n# License\n\n*The Apache 2.0 License*\n\nCopyright (c) 2010  Buu Nguyen, Morten Mertner \\\nCopyright (c) 2018 Wesley Hamilton \n\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at \n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fffhighwind%2Ffasterflect","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fffhighwind%2Ffasterflect","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fffhighwind%2Ffasterflect/lists"}