Live data from Hacker News

Beating C with 70 lines of Go

ajeetdsouza.github.io

81–90 of 106 posts

Re: Beating C with 70 lines of Go

#81
post #60
post #22

Earlier quoted context omitted.

Re: pause times, Go's garbage collector is actually really good here; you're looking at 10s of microseconds. I'm convinced the term "systems language" doesn't have a coherent meaning at this point. See: https://zenhack.net/2018/07/14/three-funerals-in-the-name-of...

Right, so when I’m trying to process a network packet in about a microsecond (a reasonable target for financial trading software), Go’s GC rules it out. Many low-level, high-performance systems language tasks aren’t feasible in Go for similar reasons. That doesn’t make it a bad language, but it’s not universally applicable either.

> but it’s not universally applicable either.

Nothing is universally applicable.

But yeah, I certainly wouldn't use it for hard real-time tasks. If you can't tolerate missing deadlines ever, there is a very short list of acceptable tools.

But (and correct me if I'm wrong; it's not my area) HFT doesn't strike me as hard real-time? See also a sibling comment that asks about Jane Street's OCaml use.

It's not like GC pauses are happening constantly; Go programs don't allocate that much, and a well tuned program can go a long time between collections. It likely is appropriate for many soft or firm real time systems. And you can shut the GC off if there are sections where GC really must not happen:

https://golang.org/pkg/runtime/debug/#SetGCPercent

Re: Beating C with 70 lines of Go

#82
post #17

Earlier quoted context omitted.

I actually disagree. If you look at the code written in the article, it's hardly unreadable or very code golf-y as you suggest. I think the author is really just trying to say that programmers shouldn't dismiss Go as a possible systems language in favor of C just because C has a reputation of being faster in all cases.

Are we really saying a garbage collected language should be considered for a systems language? I know the GC is fast but surely memory managed languages are going to have less issues with pausing during execution, no?

Esp. as a systems language. Safety first.

Re: Beating C with 70 lines of Go

#83

Earlier quoted context omitted.

You are right! So that's a Darwin oddity, still a wide char function is called in that code path, iswspace, which adds the function call overhead in a tight loop.

If domulti is not set, the wide char function is not called as far as I can tell. Why would it? It's explicitly meant not to do wide char stuff in that case. FWIW, when this was going around for the first time I took this Darwin version of wc and experimented with setting domulti to const 0, statically removing all paths where it might do wide character stuff. I didn't measure any performance difference to just runni…

It's about iswspace as I mentioned in the parent comment. Replace the line

    if (iswspace(wch))
by

    if (wch == L' ' || wch == L'\n' || wch == L'\t' || wch == L'\v' || wch == L'\f')
And I get a ~1.7x speedup:

    $ time ./wc ../wiki-large.txt
      854100 17794000 105322200 ../wiki-large.txt
    ./wc ../wiki-large.txt  0.47s user 0.02s system 99% cpu 0.490 total
    time ./wc2 ../wiki-large.txt                     
      854100 17794000 105322200 ../wiki-large.txt
    ./wc2 ../wiki-large.txt  0.28s user 0.01s system 99% cpu 0.293 total
Remove unnecessary branching introduced my multi-character handling [1]. This actually resembles the Go code pretty closely. We get a speedup of 1.8x.:

    $ time ./wc3 ../wiki-large.txt
      854100 17794000 105322200 ../wiki-large.txt
    ./wc3 ../wiki-large.txt  0.25s user 0.01s system 99% cpu 0.267 total
If we take the second table from the article and divide the C result (5.56) by 1.8, the C performance would be ~3.09, which is faster than the Go version (3.72).

Edit: for comparison, the Go version from the article:

    $ time ./wcgo ../wiki-large.txt
      854100 17794000 105322200 ../wiki-large.txt
    ./wcgo ../wiki-large.txt  0.32s user 0.02s system 100% cpu 0.333 total
So, when removing the multi-byte character white space handling, the C version is indeed faster than the (non-parallelized Go version).

[1] https://gist.github.com/danieldk/f8cdaed4ba255fb2954ded50dd2...

Re: Beating C with 70 lines of Go

#84

Earlier quoted context omitted.

No, it's not faster. They are comparing a Go version that does not do character decoding (which is necessary for correctly counting the number of words under the presence of non-ASCII punctuation) to a C version that does decode characters (and matches them against a larger character set with iswspace ). This can be easily shown, by counting words and lines using wc separately. Word counting decodes characters (to fi…

This is not true, see my comment here: https://news.ycombinator.com/edit?id=21587907

Take the Darwin version linked from your site. Run perf record wc thefile.txt. Then run perf report and you will see iswspace in the call graph.

As I show in [1], removing this call and replacing it by a character match, gives a speedup of almost 2x.

[1] https://news.ycombinator.com/item?id=21592089

Re: Beating C with 70 lines of Go

#85
post #60
post #22

Earlier quoted context omitted.

Re: pause times, Go's garbage collector is actually really good here; you're looking at 10s of microseconds. I'm convinced the term "systems language" doesn't have a coherent meaning at this point. See: https://zenhack.net/2018/07/14/three-funerals-in-the-name-of...

Right, so when I’m trying to process a network packet in about a microsecond (a reasonable target for financial trading software), Go’s GC rules it out. Many low-level, high-performance systems language tasks aren’t feasible in Go for similar reasons. That doesn’t make it a bad language, but it’s not universally applicable either.

Just like in hard real time systems using malloc() rules C out, and its use is explicitly forbidden in certification processes.

I guess C isn't universally applicable either.

Re: Beating C with 70 lines of Go

#86
post #17

Earlier quoted context omitted.

I actually disagree. If you look at the code written in the article, it's hardly unreadable or very code golf-y as you suggest. I think the author is really just trying to say that programmers shouldn't dismiss Go as a possible systems language in favor of C just because C has a reputation of being faster in all cases.

Are we really saying a garbage collected language should be considered for a systems language? I know the GC is fast but surely memory managed languages are going to have less issues with pausing during execution, no?

I think there are already a few gc/jitted components in mainstream kernels (bpf, lua drivers). So in some points, it's not a crazy idea. Now I don't advocate for Java drivers.

Re: Beating C with 70 lines of Go

#87

Earlier quoted context omitted.

In the sense that the Go authors used "systems language", i.e. for writing things like servers and command line tools, sure why not? Go's GC pauses are extremely short (under 1ms). That shouldn't really affect much.

Source? People write CLI tools in Ruby and Node.js these days, so I really doubt that anybody would use the term "systems language" to refer to languages well-suited to building CLI tools.

https://www.wired.com/2009/11/google-announces-a-new-program...

> As a systems language, Go is intended to be used for developer applications like, for example, web servers.

Couldn't find a citation for CLI tools, but that should satisfy you (since people write web servers in Ruby and Node.js too).

Re: Beating C with 70 lines of Go

#88
post #85
post #60

Earlier quoted context omitted.

Right, so when I’m trying to process a network packet in about a microsecond (a reasonable target for financial trading software), Go’s GC rules it out. Many low-level, high-performance systems language tasks aren’t feasible in Go for similar reasons. That doesn’t make it a bad language, but it’s not universally applicable either.

Just like in hard real time systems using malloc() rules C out, and its use is explicitly forbidden in certification processes. I guess C isn't universally applicable either.

The difference is, you can write perfectly usable programs in C without littering the codebase with malloc() and free().

Re: Beating C with 70 lines of Go

#89
post #88
post #85

Earlier quoted context omitted.

Just like in hard real time systems using malloc() rules C out, and its use is explicitly forbidden in certification processes. I guess C isn't universally applicable either.

The difference is, you can write perfectly usable programs in C without littering the codebase with malloc() and free().

Just like you can in Go, as proven by TinyGo.

Or in dozen of other GC enabled systems programming languages for that matter.

Re: Beating C with 70 lines of Go

#90
post #89
post #88

Earlier quoted context omitted.

The difference is, you can write perfectly usable programs in C without littering the codebase with malloc() and free().

Just like you can in Go, as proven by TinyGo. Or in dozen of other GC enabled systems programming languages for that matter.

Tip: Give up dude.
Post reply on HN