How does D compare to Go when it comes to C interop?
Chris Wright via Digitalmars-d
digitalmars-d at puremagic.com
Thu Dec 10 08:37:16 PST 2015
On Thu, 10 Dec 2015 13:33:07 +0000, Pradeep Gowda wrote:
> I read this post about the difficulties of using go/cgo to interface
> with C code:
> http://www.cockroachlabs.com/blog/the-cost-and-complexity-of-cgo/
>
> How does D do in comparison? specifically in regards to:
>
> 1. Call overhead (CGo is 100 times slower than native Go fn call)
C calls use the C calling convention. That's the only runtime difference.
The C calling convention is fast, of course, and D's is comparable.
>From what you're saying about Go, it sounds like someone implemented the
C calling convention at runtime. A few years ago (circa 2008, I think?),
I implemented something like this in D (call a function with a series of
boxed values, specifically). It was about 150 times slower than just
calling the function directly in my brief tests.
You can use packed C structs in D, which is one thing that cgo doesn't
allow.
> 2. Memory management. (I guess D is not immune from having to manage
> memory for the C functions it calls.. but is there a difference in
> approach? is it safer in D?)
For C interop?
You can allocate memory in D and pass it to C functions. This requires
some caution. If you send a pointer to a C function that allocates memory
on the heap and stores that pointer in that memory, the GC doesn't know
about that.
If you are writing the code on both sides, you can forbid that pattern.
If you are uncertain, you can hold a reference to anything you pass to C
code until you know it's safe to discard it.
Finally, if the C code takes ownership of the pointer (and expects to be
able to realloc / free it), you must use malloc. realloc and free may
well crash if you try to realloc pointers they don't know about.
If you're using D and not calling C functions, you can easily write
memory-safe code, and there's a garbage collector to boot.
> 3. Cgorountes != goroutines (This one may not apply for D)
On the other hand, coroutines are coroutines, and D has a coroutine
implementation (core.thread.Fiber).
In Go, all IO is tightly integrated with the coroutine scheduler. The
reason it requires caution to use C from Go is that, if you perform a
blocking operation, your entire program will block, unlike what happens
if you use Go IO functions.
If you are using vibe.d, you have a similar IO model and need similar
caution. That's about it, I think. Since you can call D from C/C++, you
can implement coroutine-aware code in C that will yield at the
appropriate places.
> 4. Static builds (how easy/straight-forward is this in D?)
DUB, the D build and dependency tool, produces static libraries by
default.
More information about the Digitalmars-d
mailing list