3 ms·
> After these ports, our team has built up some expertise with Go and its compiler quirks. But you can still get burned. For example, you can very easily write
by weberc2 7y ago
> After these ports, our team has built up some expertise with Go and its compiler quirks. But you can still get burned. For example, you can very easily write data that you want to place on the cheaper stack instead onto the much more expensive heap. You won’t even know this is happening by reading over your code. That’s why, as with any new language that you require high performance from, you need to monitor processes closely and create benchmarks around CPU and memory use. And then share what you learn with the community so that this knowledge becomes less tribal.
While Go doesn't have formal semantics that let you specify whether a value is allocated on the heap or stack, it seems like it would be easy enough to create your own. The compiler has flags that cause it to output the sites where it heap-allocates--if you add comments above a function or an allocation site such as `// noalloc`, then you could write a "linter" that compares the allocation sites against those comments and errors if one of those noalloc sites allocates.
In lieu of allocation semantics, this seems like a better approach than writing performance tests for each of these sites.
- twotwotwo 7y agoI see why you'd do perf tests as well (you might fail to annotate everything that could make your function run slowly), but a static analyzer that looks at -gcflags -m output does sound like a super cool idea--direct way to check if your intuitions about the code and its compilation are right.
- weberc2 7y agoYeah, I envision fewer performance tests at a higher level of granularity. Not only might you miss annotations here and there, but allocations aren't the only thing (although they are probably the most significant) that would affect your performance and my proposal won't cover you there.
- hinkley 7y agoThere are at least two ways to fail. You can get something wrong from the start, or you can get it right and fail to keep it that way. Perf sensitive code can often be that way. Some innocent coworker comes in to add a feature and they don't get why two idioms are not equivalent from the compiler's perspective, and so they change things. Meanwhile, you're busy doing something else. The code is still correct from a testing standpoint. It still satisfies your code standards. But it no longer meets your response time expectations. It's a lot of work to maintain the sort of toolchain that lets you reliably spot this sort of thing at build time or even in pre-prod environments, and it's difficult to identify places where those tools are failing to detect problems until there's been a problem.
- weberc2 7y agoI agree with all of this. My proposal addresses exactly this problem for the allocation related bottlenecks. CI will fail if someone introduces an allocation in a noalloc—annotated block.