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) Inline the Lambda. #275

Closed
AdamSpeight2008 opened this issue Feb 5, 2015 · 16 comments
Closed

(Proposal) Inline the Lambda. #275

AdamSpeight2008 opened this issue Feb 5, 2015 · 16 comments
Labels
Area-Language Design Discussion Feature Request Language-C# Resolution-Not Applicable The issue is not relevant to code in this repo and is not an external issue.
Milestone

Comments

@AdamSpeight2008
Copy link
Contributor

Premise
Allow lambda function (in particularly LINQ) to rewritten by the compiler as inline version of the algorithm. No Closures, No Delegates

Syntax
This would be enable by prefixing the lambda with inline eg
inline (x,y)=> ;

Example

The foreach aspect of the pull request #209 could written via Aggregate.

int hash = Hash.Combine(_location.GetHashCode(), 
                       Hash.Combine(_severity.GetHashCode(), _warningLevel)); 

hash =  _messageArgs.Aggregate( hash, inline (_h, item)=> HashCode.Combine( _h, item) );
hash = HashCode.Combine( _descriptor, hash)
return hash;

would be rewritten as an inline implementation.

int hash = Hash.Combine(_location.GetHashCode(), 
                       Hash.Combine(_severity.GetHashCode(), _warningLevel)); 
/* Begin Inline (Aggregate) */
 var _h = hash;
 foreach(var item in _messageArgs)
 {
    HashCode.Combine( _h, item);
 }
hash = _h
/* End Inline ( Aggregate ) */

hash = HashCode.Combine( _descriptor, hash)
return hash;

Admittedly the produce code is slightly less efficient (an extra variable).

@gafter
Copy link
Member

gafter commented Feb 5, 2015

How do you propose that the compiler know what is inside the method Aggregate, especially considering that most compilations are against a reference assembly?

How would this affect binary compatibility?

@mattwar
Copy link
Contributor

mattwar commented Feb 6, 2015

We considered this when originally doing LINQ operators, with the assumption was that we, the compiler writers and the original LINQ API authors, knew precisely the implementation. However, that's not likely to always be true.

@omariom
Copy link

omariom commented Feb 6, 2015

@mattwar, Why not to implement this for the stock Linq operators from System.Linq namespace only?
The compiler could do many optimizations which are not available for Enumerable.* methods.

It would just increase deepness of integration of queries into the language :)

@AdamSpeight2008
Copy link
Contributor Author

I would implement it via a template function ( #174 ) , and have the compiler build it.

@omariom
Copy link

omariom commented Feb 6, 2015

The motto for the effort could be:
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
Let's make Linq to Objects as performant as loops!
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨

@RichiCoder1
Copy link

👍

@AdamSpeight2008
Copy link
Contributor Author

@gafter It could also do some form of internals embedding. ie clone and mutation of the IL of the .Aggregate and then splice it into our code.

Existing precedence Embedded Interops

@mpawelski
Copy link

Is this feature somewhat similar to inline in F#? (msdn stackoverflow)
but here you would mark Aggregate function as inline?

@AdamSpeight2008
Copy link
Contributor Author

@mpawelski That's looks (to me) to more making sure the function is polymorphic.

Let's say that .Aggregate is a pure function, then there is nothing stopping you from in-lining the body of the function, as the use site (call-site / callee-site)?

@dsaf
Copy link

dsaf commented Feb 7, 2015

Wouldn't it better to introduce a short-hand custom attribute applicable to local code instead of yet another keyword? This would be similar to F#'s units-of-measure technique.

[Inline] (_h, item)=> HashCode.Combine( _h, item);
//Equivalent of [MethodImpl(MethodImplOptions.AggressiveInlining)] (_h, item)=> HashCode.Combine( _h, item)

http://www.dotnetperls.com/aggressiveinlining

@mburbea
Copy link

mburbea commented Feb 7, 2015

@dsaf, delegate invocations never get inlined, last I checked, so the attribute isn't helping the situation.

@mattwarren
Copy link

BTW, you can have these optimisations in LINQ if you use the LinqOptimizer library, it does these optimisations:

  • Lambda inlining
  • Loop fusion
  • Nested loop generation
  • Anonymous Types-Tuples elimination
  • Specialized strategies and algorithms

However you need to re-write your queries like so:

var query = (from num in nums.AsQueryExpr()
             where num % 2 == 0
             select num * num).Sum();

which gets turned into:

int sum = 0;
for (int index = 0; index < nums.Length; index++)
{
   int num = nums[index];
   if (num % 2 == 0)
      sum += num * num;
}

@MgSam
Copy link

MgSam commented Apr 13, 2015

👍
As Linq is one of the most powerful parts of the language, and is heavily used for data manipulation, I think looking into optimizations around it is certainly a worthwhile use of time for the languages team.

@dsaf
Copy link

dsaf commented Apr 13, 2015

@mburbea I meant using an attribute instead of introducing a keyword, rather than what that specific attribute is currently doing.

@gafter
Copy link
Member

gafter commented Sep 10, 2015

What about the language disallows this today?

Why is this something that should be done by compilers as opposed to being done by the runtime?

@gafter gafter added this to the Unknown milestone Sep 10, 2015
@gafter gafter added the Resolution-Not Applicable The issue is not relevant to code in this repo and is not an external issue. label Sep 12, 2015
@gafter
Copy link
Member

gafter commented Sep 12, 2015

Since the compiler is already allowed to do this (when it can prove the result is semantically identical), there is nothing to do.

Having said that, this is something traditionally done in the JIT.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Language Design Discussion Feature Request Language-C# Resolution-Not Applicable The issue is not relevant to code in this repo and is not an external issue.
Projects
None yet
Development

No branches or pull requests