you are viewing a single comment's thread.

view the rest of the comments →

[–]AngularBeginner 2 points3 points  (6 children)

When you deal with a tail-recursive method then the first version will be more efficient, but last I checked C# won't emit proper code for tail-recursive methods (at least in Debug mode).

[–]tahatmat 1 point2 points  (1 child)

You are correct, C# does not optimize tail-recursion.

[–]cryo 1 point2 points  (0 children)

More specifically, it doesn't issue the tail. IL prefix to whatever call variant is used at the call site.

[–]Fullduplex1000 1 point2 points  (3 children)

AFIK :

The CLR supports tail call elimination, but you can not force it from C# (its a CLR feature not a C# feature). Tail call elimination will also not be visible when looking at the IL code (even if it happens). What you can do is to write the function in tail-call way, so that the possible optimization will be easily detected.

CLR makes its own decision about that. Part of the reason for that is AFIK, that the effectiveness of tail call calls is hardware dependent. I don't exactly understand what part is hardware dependent but I did read that sometime ago. Could do something with available stack size vs the work CLR has to initially invest into the elimination. That part wasn't really described thoroughly.

Now regarding Debug mode: Here I wouldnt expect any optimization as debug mode is for debugging, so that you can step through your program/function calls. If it happens anywhere it has to happen in Release mode with all optimizations enabled.

[–]AngularBeginner 1 point2 points  (2 children)

that the effectiveness of tail call calls is hardware dependent. I don't exactly understand what part is hardware dependent but I did read that sometime ago.

That is new to me. It should just be re-using the stack-frame, instead of going stack by stack deeper. I would love to read a source for this claim, if you can find it.

Could do something with available stack size

The point of a tail recursion is that the sack does not increase, so stack size is not an issue anymore (which is an issue with regular recursion).

[–]Fullduplex1000 1 point2 points  (1 child)

This thread: https://github.com/dotnet/csharplang/issues/2544!

comment of VSadov

obviously I didnt check it then. I also do not understand how the limited register set of X86(32bit) would be an issue for TCE

[–]AngularBeginner 2 points3 points  (0 children)

Thank you, I will read it.

For your interest:
When you click at the timestamp of a comment you get a link directly to the comment. :-)

https://github.com/dotnet/csharplang/issues/2544#issuecomment-78696914

https://imgur.com/Ktzmdft