2012-11-28 23 views
2

目前我正在使用Microsoft Sync Framework来同步数据库。我需要收集每个由Microsoft Sync Framework插入/更新/删除的记录的信息,并对这些信息进行处理。性能 - FunctionCall vs事件vs操作vs委托

同步速度可以超过每分钟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; 
    } 
} 

别的地方在另一个组装我有三个方法:

// Assembly2 
public class SyncInformation 
{ 
    public void HandleInsertedRecordInformation(...) {...} 
    public void HandleUpdatedRecordInformation(...) {...} 
    public void HandleInsertedRecordInformation(...) {...} 
} 

Assembly2Assembly1参考。因此Assembly1不知道需要处理收集的信息的SyncInformation类的存在。所以,我有以下选项来触发此代码:

  1. 使用事件和Assembly2
    1.1就可以订阅。 EventHandler <>
    1.2。动作<>
    1.3。使用委托
  2. 依赖注入:
    public class Assembly2.SyncInformation : Assembly1.ISyncInformation
  3. 其他?

我知道的性能取决于:使用方法调用,委托行动<>或事件处理程序的<>

  • 实施

    • OnSyncProgress
      • 开关
      • SyncInformation类

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

      所以我的问题是:

      • 什么是最有效的方法?
      • 什么是最无效的方法?
      • 有没有比在OnSyncProgress中使用开关更好的方法?
  • 回答

    9

    同步速度可以去了50.000记录每分钟。所以这意味着我的额外代码需要非常轻量级,否则将会是一个巨大的性能损失。

    不,不会。

    50K /分钟的不是方法调用的显著数,除非你需要做的上千个此类电话记录的。这种过早优化的风险。如果我们忽略故意写得不好的代码和每次通话的反思,那么调用方法的绝对最慢的方式是通过无类型代理DynamicInvoke,并且可以在我的机器上42ms内完成50k个调用。还有什么(键入代表Invoke,直接callvirt一个类或接口,dynamic,静态call等),甚至不会是可衡量的(如:这将是从字面上为0毫秒50K呼叫)。

    你会做的更好使用Profiler来看看什么是真正重要的,IMO。它几乎肯定是“做”的代码,而不是管道。

    +0

    感谢您的回答。 '50k /分钟不是大量的方法调用'我同意,但我看到订阅SyncProvider.SyncProgress事件和不订阅它之间的性能差异。 OnSyncProgress正在做的事情是(当前)1:每10.000条记录添加logline 2:增加计数器DictionaryTableStats [tablename] .RecordsDeleted ++'。有什么其他原因让我看到时间差异? 7.000.000/46分钟对7.000.000/53分钟? 20K /分钟的点球(基于时间的测试机上没有生产机生产平均50K /分钟;测试平均150K /分钟) – hwcverwe

    +1

    @hwcverwe留给后人,我想在这里点抛出。你说OnSyncProgress正在添加到日志中,但没有说明成本。在低延迟应用程序(不是说你的是,但重点值得知道)的情况下,减少日志事件会有所帮助。如果你必须登录,你可以从二进制日志中获益(避免解析文本)。要阅读日志,您将创建一个“日志阅读器”应用程序(这可能非常简单)。这个观点是在6个月前在Java的电子交易活动中提到的,这个活动是我在(Gil Azne,首席技术官Azul Systems)的。这个原则适用于C#。 –