Performance penalty when Generic.List<T>.Add is the the last statement in a function and tailcall optimization is on

旧时模样 提交于 2019-12-05 03:22:21

I think I've figured out where the problem is and why it is my misunderstanding of the problem rather than bug in the F# compiler or .NET.

The code

let add j = positions.Add (Vector3(j, j, j))

means roughly "call List<T>.Add from the tailcall position on the value Vector3(j, j, j)" while

let add1 j = positions.Add (Vector3(j, j, j)); ()

means "call List<T>.Add on the value Vector3(j, j, j) and then return unit".

Type-wise, there is no difference as List<T>.Add returns unit so I incorrectly assumed positions.Add would get called and then add would return the value unit which is the return value of List<T>.Add. However, as stated at http://blogs.msdn.com/b/clrcodegeneration/archive/2009/05/11/tail-call-improvements-in-net-framework-4.aspx, the JIT needs to perform some "stack magic" when the arguments of the tail-called function are non-trivial. And this is where the performance gap comes from. The difference is very subtle, but it is there.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!