SharpNative

A C# to Native Code (C++, D etc...) Transpiler based on Microsoft Roslyn

View the Project on GitHub afrogeek/SharpNative

What is SharpNative ?

SharpNative is a tool that generates Native Code (D, Soon C++11, Java and Swift) from C# leveraging Microsoft Roslyn to generate almost hand-written code the the target languages.

The idea is to maximize the cross-platform capabilities of C# without being tied to any vendor or platform. The Emphasis here is on Performance and Readability of the generated D Code. Comments are preserved as well.


Supported Output Languages

The Compiler in its current state only supports D as the output language. (This is due to DMD being an extremely fast compiler, so testing features is fun)


Performance -- These are very unscientific

The following are tests taken from CrossNet (one of the first C# to Native compiler efforts)

Machine:

-- Macbook Pro Retina (Mid 2012)

-- 2.6Ghz Intel Core i7

-- 16GB 1600 MHz DDR3

Some benchmarks on my Parallels Windows 8 VM: (3GB Ram, 3 Cores) using DMD with options -inline -release -m64 -O and .Net in release mode

Type Of Test C# Time (ms) D Time (ms) Speed Ratio (C#/D)
NSieveTest 18859 5450 3.46x
MatrixTest(MultiDimensional) 12359 22606 0.56x
MatrixTest(Jagged) 10156 2580 3.98x
GC Test 10657 57288 0.19x
Unsafe Test 32375 4752 6.81x
HeapSort Test 8671 3906 2.21x
Average 2.87x

Due to the produced binaries being native and better optimizations in the DMD, the generated binaries are generally much faster than their C# counterparts. Except when Garbage Collection is concerned, the D GC is much slower than that of .Net (Maybe we can port it to D). Also the current multidimensional array implementation seems lacking in performance.


Example of Generated Code

C#:

using System;

class Primes
{
    public static void Main()
    {
        var len = 1000000; // This is a comment
        var primes = AddPrimes(len);
        Console.Write(primes);
    }

    private static int AddPrimes(int len)
    {
        var primes = 0;
        for (var i = 2; i < len; i++)
        {
            if (i%2 == 0)
                continue;
            var isPrime = true;
            for (var j = 2; j*j <= i; j++)
            {
                if (i%j == 0)
                {
                    isPrime = false;
                    break;
                }
            }
            if (isPrime)
                primes++;
        }
        return primes;
    }

}

D:

module CsRoot.Primes;
import System.Namespace;
import CsRoot.Namespace;

class Primes : NObject
{

    public static void Main()
    {
      int len = 1000000;
      // This is a comment
      int primes = AddPrimes(len);
      Console.Write(primes);
    }

    final static int AddPrimes(int len)
    {
      int primes = 0;

      for (int i = 2;i<len;i++)
      {
        if(i%2==0)
        {
          continue;
        }
        bool isPrime = true;

        for (int j = 2;j*j<=i;j++)
        {
          if(i%j==0)
          {
            isPrime=false;
            break;
          }
        }
        if(isPrime)
        {
          primes++;
        }
      }
      return primes;
    }

  public override String ToString()
  {
    return GetType().FullName;
  }

  public override Type GetType()
  {
    return __TypeOf!(typeof(this));
  }
}

Documentation

Unfortunately this is all the documentation the transpiler has at the moment.


Feature List (Incomplete):


Requirements -- Testing

-- Microsoft .Net 4.0 / Mono 3.6 and above.

-- Windows 7 or Later ( The CLI Interface works on Linux and OSX)

-- A Working D Installation (LDC,DMD or GDC)

Requirements -- Development

All requirements mentioned above and:

-- Visual Studio 2013 or above

-- Visual D

Usage

If you are using the GUI interface(windows) note that DMD should be installed in "C:\\D\\dmd2\\windows\\bin\\" For the CLI interface the driver can be invoked in the following manner:

mono ./SharpNative.exe /compiler:pathtodcompiler /dcorlib:/**pathtodcorlib** /source:"pathtosourcefile" /outputtype:exe /dstdlib:pathtophobos /compileroptions:"compileroptions"

where:

-- pathtodcompiler is the path to a d compiler e.g. /usr/local/bin/ldc on mac osx

-- pathtodcorlib is the path to the included basic corlib e.g. /Projects/SharpNative/DCorlib

-- pathtosourcefile is the path to the test source file in C#

--pathtophobos is the location of phobos in your installation e.g. /usr/local/Cellar/ldc/0.15.0/include/d

--compileroptions are the compiler options to pass to dmd/ldc/gdc e.g. -inline -release -m64 -O5 -oq

What Doesn’t Work: (Also Incomplete)