10 ms·
Making a Go program 70% faster by avoiding common mistakes
- echlebek 11y agoBenchmarks are an important part of optimizing a program. Another important part of optimization is profiling. Profiling lets you see where your program is spending the bulk of its time. Then you can make informed decisions about where to direct your efforts. https://blog.golang.org/profiling-go-programs https://blog.golang.org/profiling-go-programs
- rndstr 11y agoGreat job. The title was misleading to me because I thought I'd learn something about Go but this basically boils down to these performance improvements - store results in variables and don't call the expensive method over and over - use batch queries for fetching multiple documents at once from your storage
- ranko 11y agoYou also need to make measurements before you begin and as you make code changes.
- jmngomes 11y ago...which are (basic) best practices in any programming language.
- bsaul 11y agoAnd since the optimization also was about not making a call to a database in every loop iteration if you don't need to, i'd say it's also pretty basic stuff. Am i missing something as to why this is on the front page ?
- SeanDav 11y agoIts Go. Current darling on HN. One could write a blog on how to format "hello world" in Go/Golang and it would likely make the front page, especially if it was given a catchy title like "Critical string optimizations in Go"
- coldtea 11y ago>Am i missing something as to why this is on the front page ? Only that fact that it's a social bookmarking site -- so whatever is voted gets to the front page. In other words: lots of HN readers find it interesting.
- maxxxxx 11y agoI remember reading somewhere to become a star in programming you just need to look up some papers from 10 years ago and republish them. Everybody has forgotten them since then so this stuff is suddenly innovative.
- jsight 11y agoIt is Go and the title is interesting. I suspect that many of the upvoters didn't read the article and conclusions before voting. That usually works out ok, but sometimes it results in upvoting really obvious things like this.
- laumars 11y agoAs obvious as this advice is (and to be fair, to many of us it is exceedingly obvious!) I'm constantly amazed at the amount of code I see in production services that don't use local variables for storing frequently accessed methods or functions (even from experienced developers!!) and code that fails basic load tests because developers make new database requests inside -which should be- tight loops. So I can see submissions like this still benefiting some developers.
- ant6n 11y agoNot a Go programmer here. .. Wait, you have to alias methods to get performance? Isn't that the compilers' job?
- jerf 11y agoI'm guessing what was meant was more like code where you see X.Y.Z.get("Q") over and over and over again, even though it can't change, and the X, Y, Z, and Q are never that short. Nothing Go-specific about that anti-pattern, I'm afraid.
- laumars 11y agoIndeed. And for what it's worth, the real world examples I was thinking of where developers have used this anti-pattern, the code was written in Go.
- ant6n 11y agoI feel that if X, X.Y, and X.Y.Z are const within the function, the compiler should figure that out.
- coldtea 11y agoAnd a sufficiently smart compiler/interpreter would. In practice it doesn't always. Python for example, doesn't.
- 11y ago
- thomasahle 11y agoThe first one is only necessary in languages where functions can have side effects. Otherwise the compiler can easily deduplicate that for you. In most cases you would of course still name the result yourself, as to indicate that the function call indeed is the same. However for something very semantic, such as `sum(list)`, maybe the only name you could give it, would be something like `list_sum` anyway.
- sspiff 11y ago> The first one is only necessary in languages where functions can have side effects To be more precise, it is only necessary in language where all functions can have side effects. Some language (like D) have the ability to mark a function as "pure" (without side effects), which allow the compiler to perform additional optimizations (and purity validation).
- coldtea 11y ago>The first one is only necessary in languages where functions can have side effects. Which makes it, practically speaking, almost all of them...
- imron 11y agoThe title was misleading to me because I thought I'd learn something about Go The title was misleading to me because I thought I'd learn something about Go, but instead it was about Golang. With all the AlphaGo news going on, it would be significantly less confusing if posts about Golang used 'golang' in the title, at least until we're not seeing two completely different 'go's regularly on the front page.
- runn1ng 11y agoWe can also use "baduk" (the Korean name) for the game :) "Baduk" instead of "go" also makes googling something about the game easier.
- patio11 11y agoKeep in mind that, in a field which is approximately doubling every year, about half the people in the field have less than one year of experience. Sure, advice like "avoid hitting the network when you don't have to", "avoid N+1 queries", "hash tables are more convenient to search for items than unsorted arrays", etc are pretty basic for many of us, but there was a day not so many years ago when they were news to us, too, so let's warmly welcome the more junior members of the community and assist them as we were assisted. This extends to being appropriately thankful when people write guides to avoiding problems which hit someone in month 4 of their job. Did you write that guide? Did I write that guide? No. This guy wrote that guide. Bully for this guy. The world is better off that he spent two hours on this.
- workusername 11y agoI don't agree. The web has many examples and tutorials of the basics. I come to HN for the special stuff. If I want to see a terraced house I can go to any town in the UK. I go to Barcelona when I want to see a Gaudi. Great that the author wrote this. Assuming it didn't get in the way of him doing something better then I might agree that the world is a better place (let's give that emotive defender speech stuff a kick), good for him, but I don't see that HN is a better place. This is not the first time that beginner dev Go stuff has been posted here, and hung around the top of the first page, it's increasing. If that's the direction HN is heading in, the impressive stuff displaced by junior tutorials, the Gaudis will leave, the juniors will post, watch the feedback loop.
- Cthulhu_ 11y agoThat's your opinion, but since HN and any site with a voting system is effectively a democracy, the majority disagrees. Granted, a lot of upvotes will probably be more of an encouragement to the author than saying 'this is worthy of HN', but still.
- hacker_9 11y agoAt least we moved on from hearing about a new Javascript framework everyday. Now we argue about how Go is/isn't a good language. Oh and whether AlphaGo beating Lee Sedoul marks the end of the human race, or means nothing at all.
- emehrkay 11y agoIt's like seeing this in everyone's JavaScript $('.some_selector').action(); ... $('.some_selector').anotherAction();
- Cshelton 11y agoI excluded some candidates right off the bat for this...grabbing the same element 4 times in one function....no I am not hiring you...
- Cthulhu_ 11y agoIsn't there a decent caching system behind that? OTOH, .action() could change the whole dom so that .some_selector matches something else or nothing at all, so I guess jquery couldn't make that assumption / optimization without knowing what .action() does, or without doing a deep analysis of what DOM elements .action() altered and whether the selector on the next line is affected.
- maxxxxx 11y agoI have been in discussion where somebody would argue that using a variable for $('.some_selector') would be inefficient because it's more lines of code.
- TheHegemon 11y agoThank you! That is one of my greatest pet peeves. Or needless selectors like $('div.some-div input.some-input') where the classes are never used on anything other than divs/inputs. Another thing I've seen: $('#someId #childId').
- speps 11y agoInteresting tool suggested in the comments of the article : https://github.com/uber/go-torch https://github.com/uber/go-torch
- egeozcan 11y agoI'm not against people posting their experiences about finding issues (even if trivial) in their code or learning something fundamental about db queries - I would actually encourage that. What I find a bit annoying is putting the name of the programming language they use front and center, as if it was relevant at all, to attract what is mostly called as "hype".
- laurent123456 11y agoIndeed what a clickbait title, even though there's nothing new in the article. I remember reading something very similar 20 years ago, except it was about Java.
- rileymat2 11y agoA bit off topic, but do we have a standard way to talk about performance improvements in terms of percents? This went from 131 to 76. The 70% calculation was (start-end)/end. Is this the standard method, because it seems like you would divide by the start timing.
- ant6n 11y agoI find reporting like this the wrong way around. It should be a factor requiring no addition and subtraction, like 1.7x faster. Similar with compression. If a 8kb file becomes 2kb, the compression factor should be 0.25x.
- greggyb 11y agoThis might be pedantic, and I'm sorry, but this is something I always wonder about when I talk about performance. When we say 1.7x faster, what is a fast? How does fastness increase? It's nearly 2 fasts instead of one? I think the compression sample you gave is much better. Multiply the original file size by the factor to get the new, compressed file size. This is much better than a statistic that I hear a lot about the compression in a columnstore database we use, where everyone says "7-10x compression", because that was published first and is popular. I'd prefer to see something like your compression example. It took 8 seconds before, and now takes 2. My optimization makes the operation take .25x the time.
- over 11y ago1.7x faster means oldRunningTime / newRunningTime = 1.7. Or in your example, 8 seconds / 2 seconds = 4x faster. Sometimes this is called a speedup of 4x or a 4x speedup.
- greggyb 11y agoI totally get how the math works. I don't like the language. We're not measuring speed or velocity which can be represented as rates. We're measuring time. Speed would be something like operations per second. We're just measuring seconds.
- blablabla123 11y ago> [Go] benchmarks are your friend > Try not to query your database if possible. Actually this is quite generic and applies to any platform...
- unfunco 11y agoI'm not sure if Go optimises your condition, but you're calling strings.ToLower(trade.TransactionType) twice, you could memoize the result of that operation and possibly squeeze a little more performance out of the impact function.
- al2o3cr 11y agoI'd also recommend that the author look into tidying up the `TransactionType` field at ingest - those `ToLower` calls aren't free either, and if you've got control of the system writing the data it's easier to just store a consistent case. Failing that, `EqualFold` may be worth looking at. It expresses the same intent, dunno if it's more or less efficient.
- meshko 11y agoSadly the important wisdom is missing from the post -- profile, then optimize.