性能 - FunctionCall vs Event vs Action vs Delegate

hwc*_*rwe 2 c# performance events delegates dependency-injection

目前我正在使用Microsoft Sync Framework来同步数据库.我需要收集Microsoft Sync Framework插入/更新/删除的每条记录的信息,并对此信息执行某些操作.

同步速度可以超过每分钟50.000条记录.这意味着我的附加代码需要非常轻量级,否则会造成巨大的性能损失.

Microsoft Sync Framework SyncProgress为每条记录引发一个事件.我订阅了这样的代码:

// Assembly1
SyncProvider.SyncProgress += OnSyncProgress;
// ....
private void OnSyncProgress(object sender, DbSyncProgressEventArgs e)
{
    switch (args.Stage)
    {
        case DbSyncStage.ApplyingInserts:
            // MethodCall/Delegate/Action<>/EventHandler<> => HandleInsertedRecordInformation 
            // Do something with inserted record info
            break;
        case DbSyncStage.ApplyingUpdates:
            // MethodCall/Delegate/Action<>/EventHandler<> => HandleUpdatedRecordInformation  
            // Do something with updated record info
            break;
        case DbSyncStage.ApplyingDeletes:
            // MethodCall/Delegate/Action<>/EventHandler<> => HandleDeletedRecordInformation
            // Do something with deleted record info
            break;
    }
}
Run Code Online (Sandbox Code Playgroud)

在另一个程序集中的其他地方,我有三种方法:

// Assembly2
public class SyncInformation
{
    public void HandleInsertedRecordInformation(...) {...}
    public void HandleUpdatedRecordInformation(...) {...}
    public void HandleInsertedRecordInformation(...) {...}
}
Run Code Online (Sandbox Code Playgroud)

Assembly2有参考Assembly1.所以对于需要处理所收集信息Assembly1SyncInformation类的存在一无所知.所以我有以下选项来触发这段代码:

  1. Assembly2
    1.1中使用事件并订阅它.EventHandler <>
    1.2.行动<>
    1.3.代表
  2. 使用依赖注入:
    public class Assembly2.SyncInformation : Assembly1.ISyncInformation
  3. 其他?

我知道性能取决于:

  • OnSyncProgress
    • 开关
    • 使用方法调用,委托,Action <>或EventHandler <>
  • SyncInformation类的实现

我目前不关心这个SyncInformation类的实现.我主要关注OnSyncProgress方法以及如何调用SyncInformation方法.

所以我的问题是:

  • 什么是最有效的方法?
  • 什么是最无效的方法?
  • 有比使用开关更好的方法OnSyncProgress吗?

Mar*_*ell 9

同步速度可以超过每分钟50.000条记录.这意味着我的附加代码需要非常轻量级,否则会造成巨大的性能损失.

不,它不会.

50k /分钟不是大量的方法调用,除非你需要为每个记录做数千个这样的调用.这种过早优化的臭味.如果我们忽略故意编写错误的代码和每次调用的反射,那么调用方法的绝对最慢的方法是通过无类型委托DynamicInvoke,并且可以在我的机器上在42ms内进行50k调用.其他任何事情(类型代理Invoke,直接callvirt在类或接口上,dynamic静态call等)甚至都不可测量(如:对于50k调用,它将是0ms).

最好使用分析器来查看真正重要的内容,IMO.它几乎肯定是"做"代码,而不是管道.