Live data from Hacker News

Making a Go program faster with a one-character change

hmarr.com

201–210 of 249 posts

Re: Making a Go program faster with a one-character change

#201

Earlier quoted context omitted.

I work on a code base that is a mixture of Go and C. It's IO, CPU and Memory hungry, and it's distributed. C is fast because it's close to how CPU and memory actually work. Go gives you 95+% of that plus easy to learn, easy to use language. A new person could start contributing useful features and bug fixes immediately. A senior person could get C-level performance. More and more of our code is moved from C to Go, wi…

Here’s an article that refutes your claims. https://queue.acm.org/detail.cfm?id=3212479

I know about this article. Thank you.

I said C is "close to" how a computer works. C is an abstraction, and most (all?) cpu architectures pretends to be c machines. There was a talk (Kelly?) where even assembly is nowhere close to what a cpu actually does.

I don't know of any other way of manipulating the cpu as closely as C and assembly. Do you?

Re: Making a Go program faster with a one-character change

#202

Earlier quoted context omitted.

I work on a code base that is a mixture of Go and C. It's IO, CPU and Memory hungry, and it's distributed. C is fast because it's close to how CPU and memory actually work. Go gives you 95+% of that plus easy to learn, easy to use language. A new person could start contributing useful features and bug fixes immediately. A senior person could get C-level performance. More and more of our code is moved from C to Go, wi…

> C is fast because it's close to how CPU and memory actually work. Out-of-order execution, cache hierarchies, branch prediction, virtual memory, pipelining, vector instructions, ILP, NUMA are all pretty transparent to the C spec. Trying to accommodat hardware quirks with C feels like blackbox engineering. It's certainly better than with managed languages but still....

C is an abstraction, and most (all?) cpu architectures pretends to be c machines.

I don't know of any other way of manipulating the cpu as closely as C and assembly. Do you?

Re: Making a Go program faster with a one-character change

#203
post #24

If you want to have a solid understanding and need to do it in just a few hours here's a few things to review. - The Go programming language spec https://go.dev/ref/spec - Effective Go https://go.dev/doc/effective_go - Advanced Go concurrency patterns https://go.dev/talks/2013/advconc.slide#1 - Plus many more talks/slides https://go.dev/talks/

I created this video on concurrency (maybe advanced) patterns a while back that some may find helpful but it's pretty long https://www.youtube.com/watch?v=U3_2xiPxyA8 .

This was really good. You should do more of these. Cheers.

Re: Making a Go program faster with a one-character change

#204
post #124

Earlier quoted context omitted.

But 70% more stuff in the same time is 70% faster.

Let's say you do 10 things in 100 time (100/10 =10 time per thing) to start with: 70% more stuff in the same time is 17 things in 100 time (100/17 =5.9 time per thing); 70% faster is 10 things in 30 time (30/10 =3 time per thing) - or, I would argue incorrectly, perhaps said to mean 10 things in 70 time (70/10 =7 time per thing).

90mph is 50% faster than 60mph. 17/time is 70% faster than 10/time.

You're describing "in 70% less time", not "70% faster".

Re: Making a Go program faster with a one-character change

#205
post #165

Earlier quoted context omitted.

This is why I like https://github.com/openrewrite so much. One gets to tell users how to rewrite code automatically. It makes refactoring almost as easy as in a mono repo.

This looks super interesting, but as far as I can tell they don’t go into how to inform downstream users to add your recipes to their maven/gradle configuration when you make a breaking change. In my head, the ideal flow would be an annotation on your library function/class which triggers an IntelliJ suggestion for downstream users affected by your breaking change to run the automated refactor for them. Kinda like a…

It would definitely be nice to have this generated from a deprecated like annotation!

The maven plug-in seems to use the recipes directly as dependencies: https://github.com/openrewrite/rewrite-maven-plugin

In our internal situation the parent Pom could already control this plug-in definition including versions of the recipes. At the very least the recipes could follow the same version as the artefact.

I thought I saw somewhere where the recipe was bundled with the artefact itself. That is very neat for simple usecase.

However, it suffers from the same flaw as the native-image configuration for GraalVM in artifacts. Sometimes the configuration/recipe needs to change. Eg because of new insights or because it is incompatible with new versions of GraalVM/open rewrite. So I suppose having an extra version dimension Could solve this. Then one can always depend on the latest version of the recipe for that artifact.

Re: Making a Go program faster with a one-character change

#206
post #26

I was trying to debug and improve the performance of some parallelized C++ code over the weekend for parsing CSV files. What would happen was parsing each file (~24k lines, 8 columns) would take 100ms with one execution context, but when split across many threads, the execution time of each thread would slow down proportionally and the throughput of the whole program would strictly decrease as thread count increased.…

Maybe date related code calls out to the operating system to find your time zone, and maybe that can't be done in parallel.

Re: Making a Go program faster with a one-character change

#207
post #42

Earlier quoted context omitted.

IMHO, implicit allocations is a bit of a red herring. Yes, in C/C++ heap allocations are proportionately pretty expensive, but I've seen Java programs have just ridiculous amounts of implicit allocations but there really isn't much of a problem. But allocations aren't the same as copies, and the argument for reference semantics has always been that implicit copies are problematic. In your std::string example, having…

> Yes, in C/C++ heap allocations are proportionately pretty expensive, but I've seen Java programs have just ridiculous amounts of implicit allocations but there really isn't much of a problem. Java programs make "ridiculous amounts of implicit allocations" because allocations are cheap in Java. And they need to be cheap because Java doesn't have value semantics so it leans hard on escape analysis + cheap allocations…

OCaml and Standard ML.

Re: Making a Go program faster with a one-character change

#208
post #144

Earlier quoted context omitted.

What do you consider a ‘long’ pause time? I’ve had no issues with Java 17+ under heavy allocation/garbage collection (data encryption pipeline I haven’t tuned to reuse buffers yet), and it’s pause times are on the order of a handful of milliseconds, without meaningful tuning. I think it’s doing something like a GB/s of garbage collection. And the jvm in question is doing a LOT more than just this, so it’s coping with…

I consider tens of milliseconds to be a long pause time (P99 should be more explicit .

If one cares about pause times, G1 isn't it, rather the pauseless ZGC, Azul's C4 or Shenodah.

Capable of handling TB sized heaps with micro seconds pauses.

Re: Making a Go program faster with a one-character change

#209

Earlier quoted context omitted.

I also have a background in C/C++, etc and I've only ever found myself missing value semantics when I use languages with implicit reference semantics. I guess I always figured the solution was "value semantics with better education / tooling". Education: people should understand value semantics. Tooling: imagine an IDE that highlights allocation points automatically (or perhaps the problem is implicit allocations rat…

The JetBrains IDEs can do this, at least for .NET

VS did it first with Roslyn plugins.

Re: Making a Go program faster with a one-character change

#210

Earlier quoted context omitted.

I'm a dumb dumb. Can you define "implicit reference semantics" and "value semantics"? You use the phrases several times in your post, but I don't really understand what you mean. If it helps, I'm not a C++ programmer, but I am familiar with higher level languages like Go, Python, Ruby, PHP and Javascript.

Languages like Python, Java, and C# have implicit reference semantics. When you create an object, you get a pointer to that object (usually, or commonly). In languages like C, C++, Go, Rust… references are more explicit. If you want a pointer to an object, you have to &, or something similar. It gets a bit fuzzy.

On C#, we also have structs with value semantics, and arrays can be stack allocated.
Post reply on HN