Have you converted it by c2nim initially? I have no idea about your goal of course -- low level code is still low level even when coded in low level Nim...
First a remark about your proc proc `toref`[T](x: var T): ref T = cast[ref typeof(x)](x.addr) Run that can not really work, you can not cast an arbitrary variable of type T to a ref. In Nim a ref is a GC traced reference to an object, there is a refcount and type information involved, which is much more than a plain pointer. So delete this proc now! Have you verified size of type tnode_t* = object nodetype*: int32 normal*: array[3, float32] dist*: float32 children*: array[2, int32] pad*: int32 Run I am not sure, but I would guess that when you not mark this object with pure pragma, then there may be additional type information included in the object instance -- making it larger and decreasing number of instances in cache. I can't see other issues on a first look, you may have to compare line by line. Maybe inspect Nim's intermediate C code. Tiny differences may make big differences in performance, for example the original C code may be optimized that the C compiler generates fine SIMD instructions, which may not work with Nim's C output. But of course it is great that your Nim version works at all!