2012-01-22 21 views
2

是否有任何性能影响实施引用透明的方法作为静态只读Funcs而不是简单的方法?就我个人而言,我发现Func的版本更具可读性,但传统方式可能更有效。只读功能与方法,性能影响/底层的东西

此:

static readonly Func<DateTime, DateTime> TruncateDay = 
    date => date.AddHours(-date.Hour) 
       .AddMinutes(-date.Minute) 
       .AddSeconds(-date.Second) 
       .AddMilliseconds(-date.Millisecond); 

static readonly Func<DateTime, DateTime> TruncateMonth = 
    date => TruncateDay(date).AddDays(1 - date.Day); 

static readonly Func<DateTime, DateTime> TruncateYear = 
    date => TruncateMonth(date).AddMonths(1 - date.Month); 

static readonly Func<DateTime, int> QuarterSwitch = 
    date => Switch(date.Month % 3, 0, 
      Case(1, 3), 
      Case(2, 4), 
      Case(0, 5)); 

对战这样的:

static DateTime TruncateDay (DateTime date) 
{ 
    return date.AddHours(-date.Hour) 
      .AddMinutes(-date.Minute) 
      .AddSeconds(-date.Second) 
      .AddMilliseconds(-date.Millisecond); 
} 

static DateTime TruncateMonth (DateTime date) 
{ 
    return TruncateDay(date).AddDays(1 - date.Day); 
} 

static DateTime TruncateYear (DateTime date) 
{ 
    return TruncateMonth(date).AddMonths(1 - date.Month); 
} 

static int QuarterSwitch (DateTime date) 
{ 
    return Switch(date.Month % 3, 0, 
      Case(1, 3), 
      Case(2, 4), 
      Case(0, 5)); 
} 

如何在这些内部表示?编译器将每个代码翻译成什么?

+0

的可能重复的[C#更多的优点或缺点委派超过经典功能的部件?](http://stackoverflow.com/questions/8028059/c-sharp-more-advantages-or-disadvantages-to-委托 - 成员 - 经典 - 功能) – CodesInChaos

+0

我不会说,因为委托是委托,方法是方法。一旦你声明了一个方法,它就不能成为其他任何东西。而代表们可以随时更改他们指向的方法。我的问题不是关于代表。 – TheIronKnuckle

+0

我也更感兴趣哪个更快,以及两者之间的差异,而不是优势/劣势 – TheIronKnuckle

回答

5

引擎盖下,编译器创建用于每个Func方法2个另外的成员:

  1. 静态方法,其基本上相同于传统方法。
  2. 与您的委托类型相同的“缓存委托”字段。

缓存的委托字段的原因是编译器需要这样的代码中出现的匿名方法。在这种情况下,编译器不会优化字段。

该类还需要一个静态构造函数来为每个方法初始化这两个字段。

一些对性能的影响是:

  • 没有在不必调用私有静态函数小的开销。随着参数列表大小的增加,这种开销会增加。
  • Func方法不能被内联。这对于非常小的方法可以产生很大的影响。
  • 您的班级的元数据将增加大约3倍。这不是免费的,但其影响难以量化。

一些使用此的其它缺点是:

  • 超载是不可能的。
  • 在Intellisense中未拾取参数名称。
  • 它以多种方式违反了期望,包括方法在语句完成列表中显示为字段的事实。
3

在一个简单的循环中尝试着你的TruncateDay,我得到的方法速度稍微快一点 - 足够接近以至于使用该方法的最慢运行速度比使用委托的最慢运行速度慢,但仍然大致一致,代表倾向于一致只是性能稍差一点而已。

然后我试着用一个只返回传递给它的值的版本。我的计划是要有一个绝对可以接受的方法,方法版本比代表版本快大约5倍。显而易见的结论是,这个方法确实是内联的,代表并不是,尽管这当然是猜测。

尽管如此,这足以表明至少有一些优化是针对非代表的方法进行的。考虑可能还有更多,这不是不合理的。

+0

经验数据收集。 Whoda thunk? :) –

+0

当然,既然我们现在已经有了表达式主体的语法,那么任何发现问题语法更具可读性的人都会发现它仍然具有更高的可读性,所以至少不再是原来的原因。 –

2

如果他们的身体本身便宜,静态方法会快得多。如果身体很贵,那并不重要。

JIT不能内联委托内容,它必须使用间接调用。这两个都很糟糕(对于廉价的方法)。

此外,从代码质量角度来看,这是不能接受的:

  • 更多代码
  • 对于大多数人来说不易阅读,因为他们习惯了传统的风格
  • 没有重构支持
  • 反传统成语
  • 更复杂

我强烈建议您在这种情况下采用传统方式。如果我是项目负责人,我不会在没有特殊原因的情况下容忍这些代码。

+1

+1,这些也会做出很好的扩展方法,只有它们是...方法才可能。 –

+0

这是为什么downvoted?我回答了这个问题,另外我提供了建筑建议。这是一个礼貌留下评论为什么你低估了。 – usr

+0

我完全同意你的评价,并且不赞同downvote,尤其是因为没有提供任何评论。所以......我赞成抵消。 :) –

0

它可以帮助我,希望它能为你做同样的事情。

grid.Sort.Enabled = false; 
grid.Data Source = _data source_; 

//Add a single object to the beginning of the grid 
grid.Nodes.Insert(0, _new_object_); 

//Add a single object to the beginning of the binding list 
I Binding List bl = ...; 
bl.Insert(0, _new_object_);