isa*_*h_p 19 .net performance f# struct inline
我正在研究一些重的cpu绑定问题.当我使用inline关键字时,我看到了很大的性能提升.我从标准.net库创建一个字典,传入自定义密钥Comparer,请参阅下面的代码和时序结果
https://gist.github.com/4409734
在Eq_cmp上没有内联关键字
> perf_run 10000000 ;;
Real: 00:00:11.039, CPU: 00:00:11.029, GC gen0: 771, gen1: 3, gen2: 1
val it : unit = ()
Run Code Online (Sandbox Code Playgroud)
在Eq_cmp上使用内联关键字
perf_run 10000000 ;;
Real: 00:00:01.319, CPU: 00:00:01.388, GC gen0: 1, gen1: 1, gen2: 1
val it : unit = ()
>
Run Code Online (Sandbox Code Playgroud)
我还注意到Gen 0 GC与内联代码和非内联代码的巨大差异.
有人可以解释为什么会有这么大的差异吗?
pad*_*pad 18
添加inline关键字后,我可以在我的机器上重现3倍性能提升.
在ILSpy下并行反编译两个版本可以得到几乎相同的C#代码.明显的区别在于两个相等的测试:
// Version without inline
bool IEqualityComparer<Program.Pair<a>>.System-Collections-Generic-IEqualityComparer(Program.Pair<a> x, Program.Pair<a> y)
{
a v@ = x.v@;
a v@2 = y.v@;
if (LanguagePrimitives.HashCompare.GenericEqualityIntrinsic<a>(v@, v@2))
{
a w@ = x.w@;
a w@2 = y.w@;
return LanguagePrimitives.HashCompare.GenericEqualityIntrinsic<a>(w@, w@2);
}
return false;
}
// Version with inline
bool IEqualityComparer<Program.Pair<int>>.System-Collections-Generic-IEqualityComparer(Program.Pair<int> x, Program.Pair<int> y)
{
int v@ = x.v@;
int v@2 = y.v@;
if (v@ == v@2)
{
int w@ = x.w@;
int w@2 = y.w@;
return w@ == w@2;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
通用等式的效率远低于专用版本.
我还注意到Gen 0 GC与内联代码和非内联代码的巨大差异.
有人可以解释为什么会有这么大的差异吗?
看看F#源代码中的GenericEqualityIntrinsic函数:
let rec GenericEqualityIntrinsic (x : 'T) (y : 'T) : bool =
fsEqualityComparer.Equals((box x), (box y))
Run Code Online (Sandbox Code Playgroud)
它对参数进行装箱,这解释了第一个例子中的大量垃圾.当GC过于频繁地发挥作用时,它会大大减慢计算速度.第二个例子(using inline)在Pairstruct 时几乎不产生垃圾.
也就是说,inline当在呼叫站点使用专用版本时,这是关键字的预期行为.我的建议始终是尝试在相同的基准测试中优化和测量您的代码.
你可能对一个非常相似的线程感兴趣为什么这个F#代码这么慢?.
Jon*_*rop 16
输入专业化
没有inline,你使用的是非常低效的泛型比较.使用时inline,删除通用性并int直接使用比较.
| 归档时间: |
|
| 查看次数: |
1483 次 |
| 最近记录: |