13 ms·
Surprising result while transpiling C to Go
- akhenakh 4y agoAuthor of the blog post here, thanks for all the nice comments, you are lovely :) First I did not post it here, the intent was to promote ccgo to the Go community. I did recreate geoToH3 using the transpiled code and it is outperforming the helper tool provided by the C version see https://github.com/akhenakh/h3-bench/blob/main/cmd/geoToH3/main.go https://github.com/akhenakh/h3-bench/blob/main/cmd/geoToH3/m.... I hoped it was clear in the blog post: this is a very specific case where I only needed to convert coordinates to h3 index, with this specific goal this transpiled version outperform the cgo version. The comment "probably due to Go runtime scaling on multiple cores" was me still seeing very close performance with GOMAXPROCS set to 1, but observing the process behaving differently than the pure C version. The fact it was not thread safe has been discussed already on Reddit and is not relevant nor an issue when used in a batch scenario like this. ccgo is awesome, but feel free to discuss something else ;)
- randyrand 4y agoThis is an incredibly useful tool. I have a large C codebase for an embedded device, and I've often thought about the work involved in one day porting it to Embedded Linux with a higher level & safer language. This kind of tool is a game changer.
- brabel 4y agoThe transpiled Go code seems to end up having to use lots of unsafe code, as even this little sample shows... it would probably be impossible to translate C without doing that. Is the resulting binary actually memory safe in any meaningful way, or even safer than the original C?
- xyzzy_plugh 4y agoThe unsafe parts, surely not. That's not entirely the point though. Dropping a dependency on C is a big deal in Go: faster calls, no CGO means faster builds and static binaries. Go also let's you hand-write assembly and link it in, usually for performance reasons, which very much lacks safety guarantees, but has proven to be incredibly useful for optimizing hot code paths.
- turminal 4y agoUnfortunately a lot of embedded devices can't handle the size of go executables.
- randomdata 4y agoThe gc compiler produces notoriously large executables but Go programs need not be so large. A small program compiled using the tinygo compiler can be as small as 10s of kilobytes.
- Fnoord 4y agoSomeone even developed a complete SOHO router in Go: Router7 [1]. [1] https://router7.org/ https://router7.org/
- m45t3r 4y agoThis certainly doesn't look like a embedded device though: > The reference hardware platform is the PC Engines™ apu2c4 system board. It features a 1 GHz quad core amd64 CPU, 4 GB of RAM, 3 Ethernet ports and a DB9 serial port.
- p_l 4y ago"Embedded" has no relationship with size, though. And that's moderately big for "embedded" anyway.
- detaro 4y agoThat's an embedded device, sure. Embedded doesn't mean "microcontroller only".
- m45t3r 4y agoI didn't mean to imply this. I consider most router hardware embedded, but they includes CPUs. It is just that they're CPUs that you would generally consider embedded (like a SoC). And BTW, my reply was mostly because of the context: people were talking about binary sizes for Go, but if you're using PC-like hardware you wouldn't care about binary sizes anyway (you can simply put more storage, even something like a 1GB SD Card would be way bigger than something like OpenWRT that can run with hardware as low as 8MB of Flash memory).
- nicklaf 4y agoHeh, I wonder if anyone has tried transpiling the C generated by Chicken Scheme to Go. Would be interesting to see how (horrifically?) the garbage collector would fare in performance once it's transpiled to a garbage collected language like Go.
- kubb 4y agoWhat would also be nice is an ML or Lisp transpiled to Go. Go has a nice compiler with a lot of money thrown into it, but it's locked into one syntax, and set of language features that isn't optimal for every use case, so it's a good target for transpilation. It would be fun to see Go with a terser syntax, better type inference, nicer error handling, etc.
- anon_d 4y agoCompiling functional languages to other high-level language s generally has pretty awful performance compared to simple native compilation. Even compiling to C has it's limitations. The fact that Go has a nice compiler doesn't really help, because the code generated by the functional compiler will have usage patterns that are very different from what the Go compiler is designed around.
- kaba0 4y agoNot trying to start a flame war, but.. is the Go compiler nice? Other than being fast, and static compilation what good features does it have compared to say the LLVM toolchain? It barely does any optimizations.
- dividedbyzero 4y agoSomething like that would be amazing, like the godsend that Scala was for the JVM back when Java was very, very imperative and totally stagnant, though Scala didn't/doesn't transpile to Java, but compiles to JVM bytecode directly. I don't think the same would be possible for Go, which is a shame, but AFAIK there is no such intermediate to target. And given how limited Go itself is, I wouldn't be all that optimistic that a transpiling approach could support many advanced features without tanking performance because you just can't model them efficiently in Go at all, even if you limit enforcement of most guarantees to the transpiler.
- bsdetector 4y ago> It’s not only working it’s as fast and sometimes faster than the C code The C version calls latLngToCell() and the Go version calls FromGeo(). What an amazing tool that can completely change function names when it converts from C to Go. > probably due to Go runtime scaling on multiple cores. I'm sure that's it... on a single-threaded microbenchmark not running the same code.
- floor_ 4y agoMy bullshit detector is going off as well.
- benhoyt 4y agoI think your pushback is good - I didn't think the explanation about multiple cores made sense either. The Go runtime doesn't magically spread things across cores. However, I don't think your sarcasm helps the conversation.
- Thaxll 4y agoHmm yes it does actually, when you run something in a goroutine ( go keyword ) that's what I would call "magic".
- rowanG077 4y agowhat? Magic would be if Go could run single threaded code in multiple threads automatically and efficiently. The Go keyword is just a thread start for a green thread. There is nothing magical about it.
- AtNightWeCode 4y agoBenchmarks are almost always wrong. This also seems flawed.
- _gabe_ 4y agoI know the author ended up with code that was the same speed at the end of all this, but if you're ever intentionally refactoring code just to make testing easier (and not to aid in the readability or overall architecture) isn't that usually a bad design decision? Further, if you're intentionally refactoring code that you know may slow it down 2x just to aid in writing tests, isn't that a bad reason to refactor that code? > The result library is often slower than pure C (~2x magnitude) but still having a native Go port could simplify some aspects of the workflow like testing.
- xwolfi 4y agoNope, if code wasnt testable, code was less valuable. Overall architecture doesnt bring client, doesnt ease test, doesn't speed up development, etc: it can be just a pretty picture on the architect's wall while everyone is miserable. Refactor for testing. Agreed if it's gonna double the time spent per unit of work, compromise. Do not care about the architect's pretty picture, he's not solving clients' problem, you are.
- runlevel1 4y agoIn my experience, being difficult to test is a sign that a refactor is needed anyways. Difficulty testing also creates a higher barrier to adding new features. If you can't test something, it reduces confidence that your change won't break it. If it's an extremely performance-sensitive component, then you'd obviously want to be very cautious about big changes. However, that's usually not the case.
- KerrAvon 4y agoNo, rule of thumb is that if it’s not unit testable, it’s fragile. Testability doesn’t necessarily mean you lose performance, though.
- socialdemocrat 4y agoA lot of snarky and petty comments here I must say. Regardless of how the performance improvement was achieved I think it was quite interesting to see that you could convert a big chunks of C code to Go code with minimal effort and still get good performance. I think too many here read the story as some kind of competition between Go and C, when it should be more read as how well the conversion process went. For anyone interested in going down this route, surely this is useful information. We don’t have unlimited time in this industry and thus if something like this can be done with minimal effort while retaining expected performance , then I would say that we s a good thing. Stop nitpicking as if the author tried to have final word on which language is faster.
- KerrAvon 4y agoI don’t think this is a valid read of the criticisms. You’re taking the author’s performance claims at face value, and other people are not.
- throw10920 4y agoThis is not a very useful comment. > A lot of snarky and petty comments here I must say. "Be kind. Don't be snarky. Have curious conversation; don't cross-examine. Please don't fulminate. Please don't sneer, including at the rest of the community." https://news.ycombinator.com/newsguidelines.html https://news.ycombinator.com/newsguidelines.html