I am trying to improve performance in the code below and kinda know how but not sure which is the best approach.
The first hit will take longer but subsequent hits should be quicker. Now, I could cache T (where T is a class) and then check the cache to see if "T" exists, if so - go ahead and get its related information (NamedArguments) and go through each of the NamedArguments and finally if the criteria matches, go ahead and set the value of the current property.
I just want to make it more efficient and performant. Any ideas?
var myProps = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static).Where(prop => Attribute.IsDefined(prop, typeof(MyCustomAttribute)) && prop.CanWrite && prop.GetSetMethod() != null);
foreach (var currentProperty in myProps)
{
foreach (var currentAttributeForProperty in currentProperty.GetCustomAttributesData())
{
foreach (var currentNamedArgument in currentAttributeForProperty.NamedArguments)
{
if (string.Equals(currentNamedArgument.MemberInfo.Name, "PropName", StringComparison.OrdinalIgnoreCase))
{
currentAttribParamValue = currentNamedArgument.TypedValue.Value == null ? null : currentNamedArgument.TypedValue.Value.ToString();
// read the reader for the currentAttribute value
if (reader.DoesFieldExist(currentAttribParamValue))
{
var dbRecordValue = reader[currentAttribParamValue] == DBNull.Value ? null : reader[currentAttribParamValue];
// set it in the property
currentProperty.SetValue(val, dbRecordValue, null);
}
break;
}
}
}
}
DynamicMethods or ExpressionTrees will be much* faster than reflection. You could build a cache of all property getter/setters for a type, and then cache that information in a Dictionary (or ConcurrentDictionary) with type as the key.
Expression Tree Basics
Dynamic Methods
Flow
Discover type information (e.g. on app startup).
Compile dynamic methods for each property (do all properties at once).
Store those methods in a metadata class (example follows).
Cache the metadata somewhere (even a static field is fine, as long as access is synchronized). Use the type as the key.
Get the metadata for the type when needed.
Find the appropriate getter/setter.
Invoke, passing the instance on which you wish to act.
// Metadata for a type
public sealed class TypeMetadata<T> {
// The compiled getters for the type; the property name is the key
public Dictionary<string, Func<T, object>> Getters {
get;
set;
}
// The compiled setters for the type; the property name is the key
public Dictionary<string, Action<T, object>> Setters {
get;
set;
}
}
// rough invocation flow
var type = typeof( T);
var metadata = _cache[type];
var propertyName = "MyProperty";
var setter = metadata[propertyName];
var instance = new T();
var value = 12345;
setter( instance, value );
Example Setter
Excerpted from Dynamic Method Implementation (good article on the subject).
I can't vouch that this exact code works, but I've written very similar code myself. If you aren't comfortable with IL, definitely consider an expression tree instead.
public static LateBoundPropertySet CreateSet(PropertyInfo property)
{
var method = new DynamicMethod("Set" + property.Name, null, new[] { typeof(object), typeof(object) }, true);
var gen = method.GetILGenerator();
var sourceType = property.DeclaringType;
var setter = property.GetSetMethod(true);
gen.Emit(OpCodes.Ldarg_0); // Load input to stack
gen.Emit(OpCodes.Castclass, sourceType); // Cast to source type
gen.Emit(OpCodes.Ldarg_1); // Load value to stack
gen.Emit(OpCodes.Unbox_Any, property.PropertyType); // Unbox the value to its proper value type
gen.Emit(OpCodes.Callvirt, setter); // Call the setter method
gen.Emit(OpCodes.Ret);
var result = (LateBoundPropertySet)method.CreateDelegate(typeof(LateBoundPropertySet));
return result;
}
*25-100x faster in my experience
Reflection is notoriously slow in loops, so some kind of caching would probably help. But to decide what to cache, you should measure. As the famous saying goes: "premature optimization is the root of all evil"; you should make sure that you really need to optimize and what exactly to optimize.
For a more concrete advice, attributes are attached at compile time, so you could cache a type and a list of its propertyInfos for example.
I also had similar problem once - reflection is extreemely slow.
I used caching, like you are planning and performance grow more than 10 times. It was never again be a bottleneck in performance.
I've created similar logic before where I've cached an 'execution plan' for each type encountered. It was definitely faster for subsequent runs but you would have to profile your scenario to see whether it's worth the extra code complexity and memory usage.
Related
I am trying to improve performance in the code below and kinda know how but not sure which is the best approach.
The first hit will take longer but subsequent hits should be quicker. Now, I could cache T (where T is a class) and then check the cache to see if "T" exists, if so - go ahead and get its related information (NamedArguments) and go through each of the NamedArguments and finally if the criteria matches, go ahead and set the value of the current property.
I just want to make it more efficient and performant. Any ideas?
var myProps = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static).Where(prop => Attribute.IsDefined(prop, typeof(MyCustomAttribute)) && prop.CanWrite && prop.GetSetMethod() != null);
foreach (var currentProperty in myProps)
{
foreach (var currentAttributeForProperty in currentProperty.GetCustomAttributesData())
{
foreach (var currentNamedArgument in currentAttributeForProperty.NamedArguments)
{
if (string.Equals(currentNamedArgument.MemberInfo.Name, "PropName", StringComparison.OrdinalIgnoreCase))
{
currentAttribParamValue = currentNamedArgument.TypedValue.Value == null ? null : currentNamedArgument.TypedValue.Value.ToString();
// read the reader for the currentAttribute value
if (reader.DoesFieldExist(currentAttribParamValue))
{
var dbRecordValue = reader[currentAttribParamValue] == DBNull.Value ? null : reader[currentAttribParamValue];
// set it in the property
currentProperty.SetValue(val, dbRecordValue, null);
}
break;
}
}
}
}
DynamicMethods or ExpressionTrees will be much* faster than reflection. You could build a cache of all property getter/setters for a type, and then cache that information in a Dictionary (or ConcurrentDictionary) with type as the key.
Expression Tree Basics
Dynamic Methods
Flow
Discover type information (e.g. on app startup).
Compile dynamic methods for each property (do all properties at once).
Store those methods in a metadata class (example follows).
Cache the metadata somewhere (even a static field is fine, as long as access is synchronized). Use the type as the key.
Get the metadata for the type when needed.
Find the appropriate getter/setter.
Invoke, passing the instance on which you wish to act.
// Metadata for a type
public sealed class TypeMetadata<T> {
// The compiled getters for the type; the property name is the key
public Dictionary<string, Func<T, object>> Getters {
get;
set;
}
// The compiled setters for the type; the property name is the key
public Dictionary<string, Action<T, object>> Setters {
get;
set;
}
}
// rough invocation flow
var type = typeof( T);
var metadata = _cache[type];
var propertyName = "MyProperty";
var setter = metadata[propertyName];
var instance = new T();
var value = 12345;
setter( instance, value );
Example Setter
Excerpted from Dynamic Method Implementation (good article on the subject).
I can't vouch that this exact code works, but I've written very similar code myself. If you aren't comfortable with IL, definitely consider an expression tree instead.
public static LateBoundPropertySet CreateSet(PropertyInfo property)
{
var method = new DynamicMethod("Set" + property.Name, null, new[] { typeof(object), typeof(object) }, true);
var gen = method.GetILGenerator();
var sourceType = property.DeclaringType;
var setter = property.GetSetMethod(true);
gen.Emit(OpCodes.Ldarg_0); // Load input to stack
gen.Emit(OpCodes.Castclass, sourceType); // Cast to source type
gen.Emit(OpCodes.Ldarg_1); // Load value to stack
gen.Emit(OpCodes.Unbox_Any, property.PropertyType); // Unbox the value to its proper value type
gen.Emit(OpCodes.Callvirt, setter); // Call the setter method
gen.Emit(OpCodes.Ret);
var result = (LateBoundPropertySet)method.CreateDelegate(typeof(LateBoundPropertySet));
return result;
}
*25-100x faster in my experience
Reflection is notoriously slow in loops, so some kind of caching would probably help. But to decide what to cache, you should measure. As the famous saying goes: "premature optimization is the root of all evil"; you should make sure that you really need to optimize and what exactly to optimize.
For a more concrete advice, attributes are attached at compile time, so you could cache a type and a list of its propertyInfos for example.
I also had similar problem once - reflection is extreemely slow.
I used caching, like you are planning and performance grow more than 10 times. It was never again be a bottleneck in performance.
I've created similar logic before where I've cached an 'execution plan' for each type encountered. It was definitely faster for subsequent runs but you would have to profile your scenario to see whether it's worth the extra code complexity and memory usage.
I'm trying to implement static reflection for all fields in the class.
In other words, I have to create get and set using name for all these fields.
I use the answers on Set field value with Expression tree, and came to the following solution
public class ExpressionSetterGetter
{
public class SetterGetter<T> where T : class
{
public Delegate getter;
public Action<T, object> setter;
}
public static Dictionary<string, SetterGetter<T>> GetFieldSetterGetterExpressions<T>() where T : class
{
var dic = new Dictionary<string, SetterGetter<T>>();
SetterGetter<T> setterGetter;
var type = typeof(T);
var fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
foreach (var fieldInfo in fields)
{
var targetExp = Expression.Parameter(type, "target");
var valueExp = Expression.Parameter(typeof(object), "value");
var fieldExp = Expression.Field(targetExp, fieldInfo);
var assignExp = Expression.Assign(fieldExp, Expression.Convert(valueExp, fieldExp.Type));
var fieldSetter = Expression.Lambda<Action<T, object>>(assignExp, targetExp, valueExp).Compile();
ParameterExpression objParm = Expression.Parameter(type, "obj");
MemberExpression fieldExpr = Expression.Field(objParm, fieldInfo.Name);
var fieldExprConverted = Expression.Convert(fieldExpr, typeof(object));
var fieldGetter = Expression.Lambda(fieldExprConverted, objParm).Compile();
setterGetter = new SetterGetter<T>() { setter = fieldSetter, getter = fieldGetter };
dic.Add(fieldInfo.Name, setterGetter);
}
return dic;
}
}
Now, I have these two issues.
I use type.GetFields(), but MSDN says it is a reflection method.
What means that the compiler doesn't know the type before runtime.
Am I right? If it is correct, what is the reason to use the
expression trees. As far as I know expression trees translate to the
code at compile-time time, what means almost no additional costs.
The same logic. What if I put as a parameter a list with name of
fields what have to be wrapped. In other words, instead of
type.GetFields() I simply put the names of fields as parameters.
public static Dictionary<string, SetterGetter<T>> GetFieldSetterGetterExpressions<T>(IEnumerable<string> fieldNames)
Obviously, the list can be not known at compile-time. Again, how the CLR will react?
Expression trees' output is not known in compile time, they are compiled at runtime, which is something different. Advantage of using (cached) expression trees compilation is that reflection heavy lifting is performed only once, during the expression construction and compilation. From there, invocation of the resulting delegate is very fast.
In case you are sure the list specifies only the fields that actually exist in your class and you provide only a subset of all the fields, you could, in theory, somewhat reduce the performance impact of the reflection. But you should keep in mind that you will still need the FieldInfo instances for each of them which could only be retrieved using reflection. So the overall price of invoking GetField for every known field will probably be even higher than just calling GetFields for all of them.
The easiest way to set fields value in compile time is converting your private fields to public properties. Then, you can set them as you wish.
And this is not a joke on you, it's an explanation of the difference - C# doesn't allow setting fields from outside, except using reflection API's. And those API's designed for runtime, not for compile time.
If you'd like to bend the rules and produce such a code at compilation time (precisely, at post-compilation time), you should use some third party library such as PostSharp or Fody.
And that's the end of the story, so long as you are using C# in it's current or one of the previous versions.
I'm looking for a way to avoid FieldInfo.Get/SetValue overhead, and access memory directly for a few select, known ahead of time, primitive types. (Most specifically, I'm looking to avoid any memory allocations in our custom serializer)
Basically, here's what the official way allows me to do:
System.Object o = someobject;
int inOut = 0;
var type = o.GetType();
var fieldInfos = type.GetFields(BindingFlags.Public | BindingFlags.Instance);
foreach (var fi in fieldInfos) {
fi.SetValue(o, inOut);
inOut = (int)fi.GetValue(o);
}
And here's roughly what I'd like to do:
foreach (var fi in fieldInfos) {
fixed(int* ip = o.basePointer + fi.fieldOffset) {
*p = inOut;
inOut = *p;
}
}
I would use this only for Int32, Single, and possibly bools. I'm primarily interested in getting this working on Mono, so if there's anything Mono specific available, that'd be fine.
Note: I'm well aware of the "you shouldn't be doing this", and "have you profiled it" etc. I know, and I have, which is why I'm looking into this. We have a very specific case, where we control all variables (and all code), but we would like it to work on any 'normal' class without requiring additional markup or explicit struct layout.
EDIT: I should point out that I'm not able to emit dynamic code to solve this. I'm ok with a solution requiring me to write and assemble IL up-front though.
I'm well aware of the "you shouldn't be doing this"
That is good - I'll skip this part of the explanation then, and go straight to a way of accessing fields that avoids memory allocation, while staying within the limits of managed code.
You can use LINQ expressions to construct a Func<ObjType,int> for a getter and Action<ObjType,int> for a setter. Calling these functors would let you get or set int fields as if you were accessing their methods directly.
Here is how you can make a wrapper-free getter:
public class Test
{
public int myfield;
public static void Main()
{
// Make a parameter expression to represent the object
var argExpr = Expression.Parameter(typeof(Test), "a");
// Get the field of your object (the same way as in your first example)
var field = typeof(Test).GetField("myfield", BindingFlags.Public | BindingFlags.Instance);
// Make an expression accessing the field from the parameter
var fieldExpr = Expression.Field(argExpr, field);
// Compile the expression into a functor
var getter = (Func<Test,int>)Expression.Lambda(fieldExpr, argExpr).Compile();
// Construct a test object
var tmp = new Test {myfield = 123};
// Use a wrapper to avoid "boxing"/"unboxing" of "GetValue"
int res = getter(tmp);
Console.WriteLine("Res={0}", res);
}
}
Demo on ideone.
Construct the setter in a similar way, using one more parameter of type int, and Expression.Assign. The resultant lambda will compile into an Action<Test,int> rather than Func<Test,int>, because setters do not return value.
You say, that you can't use dynamic code generation. Here are some other ideas:
If you can work with properties instead of fields, create a delegate to the property getter (https://stackoverflow.com/a/724427).
Generate IL code for your serializer at build time. Compile that into an assembly that you can load at runtime. Just generate accessor code for each and every field. I think you can access private members in IL when FullTrust and SkipVerification permissions are present.
Let's say I have an object of Type User that looks like this:
User {
Name = "Bob",
Email = "Bob#gmail.com",
Class = NULL
}
Can anyone think of a way to take that object and create an object like this:
User {
Name = "Bob",
Email = "Bob#gmail.com"
}
Using entirely generic code? Meaning, I don't want to hard code anything to do with the Type, or the Properties because this code would need to be applied to every Entity on my site. (the "User" type is an Entity by the way, so use that if it helps you code this better).
I'm just trying to come up with a solution to a problem I have and I BELIEVE that Stub Entities may fix the problem, but I need to do it without hard coding any Types or Properties.
Use reflection to achieve this:
public void CopyValues<TSource, TTarget>(TSource source, TTarget target)
{
var sourceProperties = typeof(TSource).GetProperties().Where(p => p.CanRead);
foreach (var property in sourceProperties)
{
var targetProperty = typeof(TTarget).GetProperty(property.Name);
if (targetProperty != null && targetProperty.CanWrite && targetProperty.PropertyType.IsAssignableFrom(property.PropertyType))
{
var value = property.GetValue(source, null);
targetProperty.SetValue(target, value, null);
}
}
}
Generics are not gonna help you for this case. There might be some option in the Entity Framework but i am not really known with that.
It would however be possible using Reflection. You could try something like this:
public static void CopyProperties(object a, object b)
{
if (a.GetType() != b.GetType())
throw new ArgumentException("Types of object a and b should be the same", "b")
foreach (PropertyInfo property in a.GetType().GetProperties())
{
if (!property.CanRead || !property.CanWrite || (property.GetIndexParameters().Length > 0))
continue;
property.SetValue(b, property.GetValue(a, null), null);
}
}
Keep in mind tough that this requires all the properties you want to copy to have both a public setter and getter. Also there is the difference between "deep copy" vs "shallow copy" wich means if sub-objects are also copied or only referenced. This example will only reference them so it would be a "shallow copy"
This looks like a problem for reflection rather than generics (although generics can be used as a sneaky way of caching the strategy for reflection). Unless I misread it, you want to create a new instance and copy most of the members... Which reflection is good at, albeit relatively slow. You can improve the speed by using meta-programming; on the first run (per-type) generate an optimised version, perhaps using DynamicMethod or Expression, and store a typed delegate from that. Then just use the delegate.
private Equipment GenerateDirtyPropertiesOnEntity(Equipment updatedEntity)
{
updatedEntity.DirtyProperties.Clear();
Equipment originalEntity = GetEquipmentByGuid(updatedEnitity.Guid.Value);
Type myType = updatedEntity.GetType();
System.Reflection.PropertyInfo[] properties = myType.GetProperties();
foreach (System.Reflection.PropertyInfo p in properties)
{
if (p.GetValue(originalEntity, null) == null)
{
if (p.GetValue(updatedEntity, null) != null)
updatedEntity.DirtyProperties.Add(p.Name);
}
else
{
if (!(p.GetValue(originalEntity, null).Equals(p.GetValue(updatedEntity, null))))
updatedEntity.DirtyProperties.Add(p.Name);
}
}
return updatedEntity;
}
How much speed am i sacrificing when using this?
Does anyone know of a better way to do this?
Thanks in advance
You might get better performance by trying something using the INotifyPropertyChanged interface. Instead of using reflection you can use event based modeling to accomplish the same thing.
CSLA.NET is an example of a framework that takes that approach.
Example
T SomeProperty()
{
get
{
return _someProperty;
}
set
{
if (_someProperty <> value)
{
_someProperty = value;
OnPropertyChanged("SomeProperty");
}
}
}
and then OnPropertyChanged would look something like
OnPropertyChanged(object params)
{
DirtyProperties.Add(params);
}
Keep in mind this is total air code. I can't remember how the params were constructed, but it's not actually of type object and the name of the property was included which is how you would determine which property to add to your DirtyProperties list.
You are asking 2 questions:
How much speed are you loosing?
Is there a faster way to do it
Question #1:
The answer to the first one is: it depends. Writing the property checking code by hand could be several times faster than the reflection code. However, that might not be actually be a problem depending on how often the code gets called. If the code isn't called very frequently, then you wouldn't get much for the trouble of optimizing it. If, however, it's called a lot, then optimizing it may give you big speed improvements. I would run your app underneath a profiler (I like Jet Brain's Dot Trace personally) to see where the time is actually being spent. The percentage of time spent inside "GenerateDirtyPropertiesOnEntity" will give you the theoretical maximum perf gain you can get by optimizing the method. If that ends up being a small percentage, then I would just keep the code as is.
Question #2
I can think of 2 simple ways of making this faster:
Write the property comparison code by hand.
Use the DynamicMethod class to generate the comparison code
I'm assuming you don't want to do #1. I'll post some code that shows #2 in a second.
Update:
Here's the code for generating a dynamic method
class Util
{
public static Func<T,T, List<string>> CreateDitryChecker<T>()
{
var dm =
new DynamicMethod
(
"$dirty_checker",
typeof(List<string>),
new[] { typeof(T), typeof(T) },
typeof(T)
);
var ilGen = dm.GetILGenerator();
//var retVar = new List<string>();
var retVar = ilGen.DeclareLocal(typeof(List<string>));
ilGen.Emit(OpCodes.Newobj, typeof(List<string>).GetConstructor(new Type[0]));
ilGen.Emit(OpCodes.Stloc, retVar);
var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
MethodInfo objEqualsMehtod = typeof(object).GetMethod("Equals", new[] { typeof(object) });
MethodInfo listAddMethod = typeof(List<string>).GetMethod("Add");
foreach (PropertyInfo prop in properties)
{
//Inject code equivalent to the following into the method:
//if (arg1.prop == null)
//{
// if (arg2.prop != null)
// {
// retVar.Add("prop")
// }
//}
//else
//{
// if (! arg1.prop.Equals(arg2))
// {
// retVar.Add("prop")
// }
//}
Label endLabel = ilGen.DefineLabel();
Label elseLabel = ilGen.DefineLabel();
//if arg1.prop != null, goto elseLabel
ilGen.Emit(OpCodes.Ldarg_0);
ilGen.Emit(OpCodes.Call, prop.GetGetMethod());
ilGen.Emit(OpCodes.Brtrue, elseLabel);
//if arg2.prop != null, goto endLabel
ilGen.Emit(OpCodes.Ldarg_1);
ilGen.EmitCall(OpCodes.Call, prop.GetGetMethod(), null);
ilGen.Emit(OpCodes.Brfalse, endLabel);
//retVar.Add("prop");
ilGen.Emit(OpCodes.Ldloc, retVar);
ilGen.Emit(OpCodes.Ldstr, prop.Name);
ilGen.EmitCall(OpCodes.Callvirt, listAddMethod, null);
ilGen.Emit(OpCodes.Br, endLabel);
//elseLabel:
ilGen.MarkLabel(elseLabel);
//if (arg0.prop.Equals(arg1.prop), goto endLabel
ilGen.Emit(OpCodes.Ldarg_0);
ilGen.EmitCall(OpCodes.Call, prop.GetGetMethod(), null);
ilGen.Emit(OpCodes.Ldarg_1);
ilGen.EmitCall(OpCodes.Call, prop.GetGetMethod(), null);
ilGen.EmitCall(OpCodes.Callvirt, objEqualsMehtod, null);
ilGen.Emit(OpCodes.Brtrue, endLabel);
//retVar.Add("prop")
ilGen.Emit(OpCodes.Ldloc, retVar);
ilGen.Emit(OpCodes.Ldstr, prop.Name);
ilGen.EmitCall(OpCodes.Callvirt, listAddMethod, null);
//endLAbel:
ilGen.MarkLabel(endLabel);
}
ilGen.Emit(OpCodes.Ldloc, retVar);
ilGen.Emit(OpCodes.Ret);
return (Func<T, T, List<string>>) dm.CreateDelegate(typeof(Func<T, T, List<string>>));
}
}
It takes in a generic parameter T and returns a delegate that, when given 2 T instances will return a list of all the changed properties.
To get a performance boost out of it, it's a good idea to call the method once and store the result in a readonly static field. Something like this would work:
class FooBar
{
static readonly Func<FooBar,FooBar, List<string>> s_dirtyChecker;
static FooBar()
{
s_dirtyChecker = Util.CreateDirtyChecker<FooBar>();
}
public List<string> GetDirtyProperties(Foobar other)
{
return s_dirtyChecker(this, other);
}
}
I'm looking at doing something similar using PostSharp, then comparing the old and new property value when it's being set, and flagging the object as dirty. Shouldn't be too hard to do the same things on a property level.
The only way to know, without doubt, how much speed you're sacrificing would be to profile this.
In general, in my experience, reflecting on properties seems to be, at best, about 1/50th the speed of accessing them directly. At worst it can be 200x slower. Depending on the frequency of this operation, and the number of properties, this may or may not be a noticable difference, though, which again, is why I'd suggest profiling it to tell if you need a different solution.