A C# to Native Code (C++, D etc...) Transpiler based on Microsoft Roslyn
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.
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)
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));
}
}
Unfortunately this is all the documentation the transpiler has at the moment.
Feature List (Incomplete):
-- 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)
All requirements mentioned above and:
-- Visual Studio 2013 or above
-- Visual D
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)