我有一个框架,允许用户对特定数据源(足球经理 2010 游戏数据库,对于那些感兴趣的人)进行查询。
在这个框架中,我的框架可以运行两种不同的模式:实时模式和缓存模式。我希望使用这个框架的用户能够通过调用不同的构造函数(例如new Context(Mode.Cached)
)来进行切换。这应该是用户应该进行的唯一切换,因此他仍然可以进行所有相同的 Linq 调用,但是当他的应用程序更适合时才使用缓存模式。清除。
我决定使用 PostSharp 应该是我的最佳选择,因为:
- 在每个属性上创建一个方面(已经被属性修饰过)
- 在这方面,检查我们是否处于
Cached
或Realtime
模式 - 从内存或缓存中返回值
那行得通。但!速度不够好。在 90.000 个对象上执行以下操作时:
foreach (Player p in fm.Players)
{
int ca = (short)ProcessManager.ReadFromBuffer(p.OriginalBytes, PlayerOffsets.Ca, typeof(Int16));
}
它只需要 63 毫秒。(ReadFromBuffer 是一个高度优化的函数,它接受byte[], int, Type
并返回object
),考虑到大量的对象,63 ms 是非常合理的。
但!在 PostSharp 中,我使用这个实现了相同的功能:
public override void OnInvocation(MethodInvocationEventArgs eventArgs)
{
if (eventArgs.Method.Name.StartsWith("~get_"))
{
if (Global.DatabaseMode == DatabaseModeEnum.Cached)
{
byte[] buffer = ((BaseObject)eventArgs.Instance).OriginalBytes;
eventArgs.ReturnValue =
ProcessManager.ReadFromBuffer(buffer, this.Offset, eventArgs.Method.ReturnType);
}
现在我称之为使用
foreach (Player p in fm.Players)
{
int ca = p.CA;
}
而且它需要782 毫秒,超过 10 倍!
我将方面创建为:
[Serializable]
[MulticastAttributeUsage(MulticastTargets.Method, PersistMetaData = true)]
internal class FMEntityAttribute : OnMethodInvocationAspect
{
public FMEntityAttribute(int offset, int additionalStringOffset)
{
this.Offset = offset;
this.AdditionalStringOffset = additionalStringOffset;
}
//blah blah AOP code
}
并且该物业被装饰得像
[FMEntityAttribute(PlayerOffsets.Ca)]
public Int16 CA { get; set; }
我怎样才能让它表现良好?!