Avoid boxing Booleans when dumping sync traits.

We can return the resulting strings directly.
This commit is contained in:
RoosterDragon
2017-01-11 21:11:56 +00:00
parent 9816052262
commit fbf6f45b11

View File

@@ -166,8 +166,10 @@ namespace OpenRA.Network
struct TypeInfo
{
static ParameterExpression syncParam = Expression.Parameter(typeof(ISync), "sync");
static ConstantExpression nullString = Expression.Constant(null, typeof(string));
static readonly ParameterExpression SyncParam = Expression.Parameter(typeof(ISync), "sync");
static readonly ConstantExpression NullString = Expression.Constant(null, typeof(string));
static readonly ConstantExpression TrueString = Expression.Constant(bool.TrueString, typeof(string));
static readonly ConstantExpression FalseString = Expression.Constant(bool.FalseString, typeof(string));
public readonly Func<ISync, object>[] SerializableCopyOfMemberFunctions;
public readonly string[] Names;
@@ -184,7 +186,7 @@ namespace OpenRA.Network
"Properties using the Sync attribute must be readable and must not use index parameters.\n" +
"Invalid Property: " + prop.DeclaringType.FullName + "." + prop.Name);
var sync = Expression.Convert(syncParam, type);
var sync = Expression.Convert(SyncParam, type);
SerializableCopyOfMemberFunctions = fields
.Select(fi => SerializableCopyOfMember(Expression.Field(sync, fi), fi.FieldType, fi.Name))
.Concat(properties.Select(pi => SerializableCopyOfMember(Expression.Property(sync, pi), pi.PropertyType, pi.Name)))
@@ -203,8 +205,16 @@ namespace OpenRA.Network
// just box a copy of the current value into an object. This is faster than calling ToString. We
// can call ToString later when we generate the report. Most of the time, the sync report is never
// generated so we successfully avoid the overhead to calling ToString.
if (memberType == typeof(bool))
{
// PERF: If the member is a Boolean, we can also avoid the allocation caused by boxing it.
// Instead, we can just return the resulting strings directly.
var getBoolString = Expression.Condition(getMember, TrueString, FalseString);
return Expression.Lambda<Func<ISync, string>>(getBoolString, name, new[] { SyncParam }).Compile();
}
var boxedCopy = Expression.Convert(getMember, typeof(object));
return Expression.Lambda<Func<ISync, object>>(boxedCopy, name, new[] { syncParam }).Compile();
return Expression.Lambda<Func<ISync, object>>(boxedCopy, name, new[] { SyncParam }).Compile();
}
// For reference types, we have to call ToString right away to get a snapshot of the value. We cannot
@@ -231,10 +241,10 @@ namespace OpenRA.Network
var member = Expression.Block(new[] { memberVariable }, assignMemberVariable);
getString = Expression.Call(member, toString);
var nullMember = Expression.Constant(null, memberType);
getString = Expression.Condition(Expression.Equal(member, nullMember), nullString, getString);
getString = Expression.Condition(Expression.Equal(member, nullMember), NullString, getString);
}
return Expression.Lambda<Func<ISync, string>>(getString, name, new[] { syncParam }).Compile();
return Expression.Lambda<Func<ISync, string>>(getString, name, new[] { SyncParam }).Compile();
}
}
}