3 ms·
Did you actually profile pure Go vs. Go assembly implementation of your code? You make a pretty strong statement of "bitwise operations are painfully slow comp
by kjksf 11y ago
Did you actually profile pure Go vs. Go assembly implementation of your code?
You make a pretty strong statement of "bitwise operations are painfully slow compared to the equivalent in C" and I find it hard to square that with my understanding of how things work.
Compiling simple arithmetic is about the simplest thing the compiler does. There's no reason Go compiler should produce slower code on that than a C compiler.
Also, on modern processors arithmetic operations are cheap compared to memory access.
Looking at govarint code: it could be much faster without reaching for assembly.
First, it uses interfaces. Interfaces are great but the call via interface is more expensive than a direct call (and most likely prohibits inlining). In C++ terms it's like calling a virtual function. C doesn't even have anything like that, you only get straight calls.
Given that you incur that overhead every single Put()/Get() call, even though the cost is small in absolute terms, it's large compared to cost of the code inside those functions.
If you care about absolute performance, don't use interfaces.
Second, you make another function call via interface (r.ReadByte()) for every byte of data. Again, a function call is not expensive in absolute terms, but in this case it'll be more expensive than the rest of the computation. Grab 4k into a temp buffer and process that. It'll make the code more complicated but it's not dropping to assembly.
Finally, I can be completely wrong. Profile your code (http://blog.golang.org/profiling-go-programs http://blog.golang.org/profiling-go-programs).
Now, even after those fixes I don't expect Go code to be as fast as C code. C can use slightly faster function call conventions, memory access isn't bounds checked, at O3 it'll inline more aggressively, you can force inlining manually or tell the compiler to do profile guided optimizations - all those contribute to generating faster code.
However, Go code shouldn't be "painfully" slower. If it's more than 2x slower than C, then there's probably something else going on other than weaker code generation.
- vardump 11y ago> C doesn't even have anything like that, you only get straight calls. C does have function pointers. But because it involves setting up and tearing down call frame, they're slow for calling small functions large number of times. Functionally equivalent to C++ virtual calls (through vtable). At least golang 1.2/1.3 did occasionally generate excessive number of bound checks. Once I counted no less than 6 nearly equivalent bound checks in an inner loop. It took a while of twiddling with code to get rid of all but 2. However, mostly golang performance is pretty good. I like the language, so I just rather write a C/SSE/AVX library if I really need something to be very fast.
- klauspost 11y agoI like the language, so I just rather write a C/SSE/AVX library if I really need something to be very fast. I feel exactly the same, and once you get to know the quirks of the Go assembler it is actually pretty easy to use. That said unless I know it can be done en SSE, I usually don't bother, because the speedup likely isn't worth the effort.