GithubHelp home page GithubHelp logo

solertis / roslyn-linq-rewrite Goto Github PK

View Code? Open in Web Editor NEW

This project forked from antiufo/roslyn-linq-rewrite

0.0 2.0 0.0 331 KB

Compiles C# code by first rewriting the syntax trees of LINQ expressions using plain procedural code, minimizing allocations and dynamic dispatch.

License: MIT License

Batchfile 0.52% C# 98.48% PowerShell 1.00%

roslyn-linq-rewrite's Introduction

roslyn-linq-rewrite

This tool compiles C# code by first rewriting the syntax trees of LINQ expressions using plain procedural code, minimizing allocations and dynamic dispatch.

Example input code

public int Method1()
{
    var arr = new[] { 1, 2, 3, 4 };
    var q = 2;
    return arr.Where(x => x > q).Select(x => x + 3).Sum();
}

Allocations: input array, array enumerator, closure for q, Where delegate, Select delegate, Where enumerator, Select enumerator.

Decompiled output code

public int Method1()
{
    int[] arr = new[] { 1, 2, 3, 4 };
    int q = 2;
    return this.Method1_ProceduralLinq1(arr, q);
}
private int Method1_ProceduralLinq1(int[] _linqitems, int q)
{
    if (_linqitems == null) throw new ArgumentNullException();

    int num = 0;
    for (int i = 0; i < _linqitems.Length; i++)
    {
        int num2 = _linqitems[i]; 
        if (num2 > q)
            num += num2 + 3;
    }
    return num;
}

Allocations: input array.

Note: in this example, the optimizing compiler has generated code using arrays, because the type was known at compile time. When this is not the case, the generated code will instead use a foreach and IEnumerable<>. Non-optimizable call chains and IQueryable<> are left intact.

Supported LINQ methods

  • Select, Where, Reverse, Cast, OfType
  • First, FirstOrDefault, Single, SingleOrDefault, Last, LastOrDefault
  • ToList, ToArray, ToDictionary
  • Count, LongCount, Any, All
  • ElementAt, ElementAtOrDefault
  • Contains, ForEach

Usage (.sln/.csproj)

  • Download the latest binaries
  • roslyn-linq-rewrite <path-to-sln-or-csproj> [--release]

Note: you can more deeply integrate the optimizing compiler with MSBuild by setting CscToolPath to the roslyn-linq-rewrite directory.

Usage (project.json)

  • Add the following to your project.json:
    "tools": {
        "dotnet-compile-csc-linq-rewrite": {
          "version": "1.0.1.9",
          "imports": "portable-net45+win8+wp8+wpa81"
        }
    }
  • In the buildOptions of your project.json, specify the custom compiler:
    "buildOptions": {
        "compilerName": "csc-linq-rewrite"
    }
  • Compile your project with dotnet restore and dotnet build.
  • If you need to exclude a specific method, apply a [NoLinqRewrite] attribute to that method:
namespace Shaman.Runtime
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method)]
    public class NoLinqRewriteAttribute : Attribute
    {
    }
}

Tests

Here's a diff (and its code) between the ordinary LINQ tests and the version compiled with roslyn-linq-rewrite. The only difference seems to be related about a Min/Max with NaN values, I'm planning to fix it soon.

Shaman.FastLinq

To further reduce allocations, install Shaman.FastLinq or Shaman.FastLinq.Sources. These packages include LINQ methods specific for T[] and List<> (not all method calls are optimized by LINQ rewrite, like individual, non-chained .First() or .Last() calls).

Comparison to LinqOptimizer

  • Code is optimized at build time (as opposed to run time)
  • Uses existing LINQ syntax, no need for AsQueryExpr().Run()
  • No allocations for Expression<> trees and enumerator boxing
  • Parallel LINQ is not supported (i.e. left intact)
  • No support for F#

roslyn-linq-rewrite's People

Contributors

antiufo avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.