Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Compile time expressions #12238

Closed
nvmkpk opened this issue Jun 27, 2016 · 20 comments
Closed

Proposal: Compile time expressions #12238

nvmkpk opened this issue Jun 27, 2016 · 20 comments

Comments

@nvmkpk
Copy link

nvmkpk commented Jun 27, 2016

It would be useful to specify something like "Hello World".Length in some special syntax that gets evaluated at compile time and replaced with 11 (becoming a constant) in the compiled binaries.

@nvmkpk nvmkpk changed the title Compile time expressions Proposal: Compile time expressions Jun 27, 2016
@choikwa
Copy link

choikwa commented Jun 27, 2016

You mean it's not already converted to constant?

@nvmkpk
Copy link
Author

nvmkpk commented Jun 27, 2016

JIT compiler might optimize it but I want the language compiler to do it. In the generated IL code the string is constant but the value of its length is not.

@gafter gafter changed the title Proposal: Compile time expressions Proposal: make string.Length a compile-time-constant when string is a constant Jun 28, 2016
@nvmkpk
Copy link
Author

nvmkpk commented Jun 28, 2016

I gave string as example. I want to be able to use more expressions to evaluated at compile time. Something like eval(simple expression).

@nvmkpk nvmkpk changed the title Proposal: make string.Length a compile-time-constant when string is a constant Proposal: Compile time expressions Jun 28, 2016
@svick
Copy link
Contributor

svick commented Jun 28, 2016

What is the reason? Is it about performance? Or something else?

@alrz
Copy link
Member

alrz commented Jun 28, 2016

This is also related to #10972 and #9627 (there are similar examples in the latter issue).

@nvmkpk
Copy link
Author

nvmkpk commented Jun 28, 2016

The reason is simple. If we know that the value of an expression at run time is exactly same as at compile time, there is no point in deferring evaluation to run time.

@Unknown6656
Copy link

Unknown6656 commented Jun 29, 2016

@nvmkpk : I do quite like the idea, I do however see the following problem:

Imagine, that one is writing a (memory) profiler. The profiler would not register the function call int System::String::get_Length(), as the function would be "precompiled" into its result. Thus the application profiling result could be incorrect compared to expected data/values.

My second question/concern: To which degree do you want this "optimization"? Should it apply to each completely deterministic function(-chain) with only constant input?
e.g. should the expression "Hello,World!".ToUpper().Remove(0,1) be precompiled into "ELLO,WORLD!" ? Where do we draw the line?

EDIT: or should one use a pseudo-attribute like [compile], which one could put in front of fields/expressions?

@svick
Copy link
Contributor

svick commented Jun 29, 2016

@Unknown6656 That already happens, in the JIT compiled machine code, there is no call to get_Length(), since it's inlined.

And you can't put attributes on expressions, at least not without #6671.

@Unknown6656
Copy link

Unknown6656 commented Jun 29, 2016

@svick : Interesting, I did not know the fact about get_Length()-inlining.

Concerning the usage of attributes on expressions: During the composition of my previous comment I assumed, that issue #6671 will be implemented in the future C# version, as it has been marked as
[2 - Ready]

@choikwa
Copy link

choikwa commented Jun 29, 2016

My second question/concern: To which degree do you want this "optimization"?

Hopefully in Release build, all of the optimizations.

Where do we draw the line?

Where-ever compiler can statically determine static or read-only or const-ness and exploit it 👯

@nvmkpk
Copy link
Author

nvmkpk commented Jun 29, 2016

That is fine for optimization part but I would like the developer to also call for compile time evaluation by using something like eval(expression). This would be better way than using attributes.

@Unknown6656
Copy link

Unknown6656 commented Jun 29, 2016

@choikwa (, @nvmkpk ): So, would the following expression be optimized (assuming, that a array<string> shall be interpreted as constant, and that all functions do not use non-constant internal parameters and are fully deterministic)?

char a = (new string[] { "test", "string" })[1].Reverse().ToArray()[3]) - 'B';
// a now stores the character `0`

My point is: I really do love your proposal, but does too much optimization not take too much time on a big scale? Are arrays defined at compile time also a constant, if they remain unchanged?
Imagine the calculation time for large for-loops, nested conditions etc. which will be precompiled. Does not take this too much compilation time?


If anyone is interested, how the character is calculated in the example above:

string[] arr = new string[] { "test", "string" };
char[] elem = arr[1].Reverse().ToArray(); // [g,n,i,r,s,t]
char r = elem[3]; // 'r' (0x72)
char a = r - 'B'; // 0x72 - 0x42 == 0x30 = '0'
// a now stores the character `0`

@choikwa
Copy link

choikwa commented Jun 29, 2016

would the following expression be optimized?

A compiler worth its salt would optimize. I am hoping CoreCLR is to be such one. Maybe you can help make that happen 😄

does too much optimization not take too much time on a big scale?

C++ already does this with constexpr and template meta. A saving grace is that you only do this once during compilation. In C# context, maybe this makes more sense in AOT compilation or more expensive ReJIT (don't we all want tiered JIT?).

PS. a lot of compilers already neuter optimization if method size is too large, to the detriment of performance just because compilation time would be excessive. Would not surprise me if CoreCLR had to do something similar since it's a VM.

@Unknown6656
Copy link

@choikwa I think that you have me convinced on that point! 😄
I knew that C++ has precompiled templates instead of runtime-generated generics, but I did not yet know about constexpr. I think, that this is an excellent definition of constant expressions/methods (which needs some adaptation for C#)

Maybe you can help make that happen

I will try as much as I can 😉

@choikwa
Copy link

choikwa commented Jun 29, 2016

FYI this very issue is open in https://github.com/dotnet/coreclr/issues/3633

@nvmkpk
Copy link
Author

nvmkpk commented Jun 29, 2016

That is for optimzation. This proposal is about letting developer write general compile time expressions not just for string length.

@choikwa
Copy link

choikwa commented Jun 29, 2016

Sorry for hijacking the issue. You are correct, and I agree that this should have some dependence on success of https://github.com/dotnet/roslyn/issues/6671

@ashmind
Copy link
Contributor

ashmind commented Aug 24, 2016

On the syntax -- I suggested const(...) in #11259 which has a benefit of already being a keyword.

@alrz
Copy link
Member

alrz commented Apr 20, 2017

@nvmkpk May you move this to csharplang repo?

@jcouv
Copy link
Member

jcouv commented Oct 22, 2017

Issue moved to dotnet/csharplang #1028 via ZenHub

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants