By native code I mean binaries emitted by my compiler in a format that my operating system can link and load. I usually write the code in C with some CPU-specific assembly intrinsics for the critical stuff.
I tend to write computer graphics and physics simulation stuff which has to be quite fast. A lot of stuff I deal with is moving blobs of binary data from buffer to another (disk, memory, dma, gpu). Or computing a SIMD fused multiply-and-add for a few hundred megabytes of floating point data. Or invert and transpose a hundred thousand 4x4 matrices. Everything the JVM does is acting against me, so better just write native.
Sure there are games and physics and whatnot written with Java and other systems, but they are more commonly "low perf" stuff. 2d games and that kind of stuff. And even then they suffer from JIT & GC pauses and other undesirable effects. It always ruins my day when in the middle of a Minecraft session the GC kicks in while running away from a Creeper.
The JVM is very fast for these things. There remaining delta is the result of more investment into optimizations in GCC/LLVM than any limitation of the JVM model itself.
GC, allocation, thread management, OS interfacing and compilation (JIT or AOT) together make up a VM. Removing the compilation part doesn't make the rest of your VM requirements disappear.
Having used a number of various VMs in the Common Lisp world (yes, including one implementation that went through C) I value the JVM greatly. It is an impressive engineering effort.
Also, I wrote code like yours (hand-written x86-64 SIMD assembly). I then used it from Clojure through JNA and was quite happy with the results.
Yes, you might need to free some heap memory with C and having malloc/free cause GC-like performance. That's why I have zero mallocs in the fast path. The bad part in GC is the unpredictability, which makes it unsuitable for games, simulation and multimedia stuff. But for most allocs I can get away with using the stack, which is essentially free (a possibility of a page fault exists).
> Also, I wrote code like yours (hand-written x86-64 SIMD assembly). I then used it from Clojure through JNA and was quite happy with the results.
Yes that works quite well as long as the foreign function is big enough.
What I have is a bunch of code written with C intrinsics, mostly small functions which I use a handful of for a big bunch of data. What I want is that inner loop to be efficient yet readable.
With C and intrinsics I get interprocedural optimization between the small functions. Everything gets inlined and all the values are stored in registers. There are a few hundred SSE math instructions without a single memory operation in between. I get the compiler to do register allocation for instruction scheduling for me, which it is great at (and I suck in) and leaves me with the instruction selection which it is not so great at.
Now had this been written with any higher level language, or even C across translation units (without link time optimization), my resulting code would be a lot worse. In particular, live values get spilled out of registers to memory when theres a foreign function call (as per abi requirements).
The non-fast path of my project could very well be written in any language as long as the beef would be written in C or similar. I would have to avoid allocating new heap objects to avoid GC unpredicatbility.
It'd be nice if somebody made a new systems language to succeed C or C++. Rust is looking less likely these days. Maybe Clay or Deca?
It's like the inverse of golang. golang is unimpressive, and totally impractical for systems programming, but is nice to use for general purpose programming.
Rust is impressive and could'ish be used for systems programming (I'm not sure how much uphill fighting is involved with the current memory management model, it seems ARC is the default which makes me intensely uncomfortable about its prospects for 'hard' systems programming) but it's not very pleasant at all. The syntax and semantics make me nauseous.
Rust can be fixed, golang cannot. Unlikely though.
I'm not sure it's more realistic to make a practical implementation of region-based memory management than it is to ameliorate the pains of day-to-day systems programming in C.
There is a lot of low-hanging fruit when it comes to systems programming if you're allowed to make a language from scratch and they've not really capitalized on much of that due to ambition.
For me, because I don't want to install the JVM, or force users of my stuff to install the JVM. I also don't care about JVM libs.
>What do you even mean by native code ? The JVM does produce native code, it just does it at runtime (JIT compilation).
I, for one, mean non-JIT, no virtual machine needed, native code.
>So maybe you mean static compilation, but then, why is it better for the stuff you're doing ?
Less startup overhead. Small binaries. Easily redistributable. No stuff I don't need.
So maybe you mean static compilation, but then, why is it better for the stuff you're doing ?