
Random Acts of Optimization - sled
http://engineering.riotgames.com/news/random-acts-optimization
======
saosebastiao
This brings up a thought that I've had for a very long time. Almost every type
of optimization that a programmer could employ is repeatable. It involves
matching patterns ("Identification" in the context of this article), analysis
("Comprehension"), and rewriting ("Iteration").

All of these steps can be efficiently automated. And it turns out that
compiler writers collectively know about the vast majority of these
techniques, but refuse to implement most of them for what I would consider to
be the ultimate copout ever: Compile times. I don't know about you, but I
would take 100x increase in compilation times for a release build over a 2x
increase in development time due to manual optimization. I'm not sure who
wouldn't, especially if it also allows you to eliminate technical debt,
eliminate leaky abstractions, and improve code comprehensibility.

Perhaps I'm being overly idealistic, but I can't help but hope for a day that
I can work with a high level language and have the compiler take care of
optimizations that range from removing redundant elements from struct
definitions all the way down to bitshift optimizations like i * 28 == i<<4 +
i<<3 + i<<2\. And if I have to wait all day long for a release build of
something, so be it.

~~~
evincarofautumn
Insulation from performance concerns also makes your performance model less
predictable. Because the _ends_ of optimisations are observable, but their
_means_ are not, people resort to “butterfly programming”. As a small example,
in ActionScript 3, people used to write their conditionals like this:

    
    
        if (a) if (b) {
          ...
        }
    

Rather than this:

    
    
        if (a && b) {
          ...
        }
    

Because the dumb compiler generated better code for the former.

In the real world, I’ve seen seemingly benign code changes prevent
optimisations from firing—optimisations we didn’t know we were relying on. So
people start coding to the implementation, rather than the language or the
human, _without even being able to see what they’re doing_. I _really_ don’t
like that.

Optimisers are like garbage collectors—they give you better ergonomics than,
and equal _average_ performance to the manual alternative, if you’re willing
to relinquish predictability and a non-voodoo mental model of your code’s
performance.

~~~
WalterBright
> I really don’t like that.

Unfortunately, the nature of optimizations makes tracking these sorts of
things really hard. They don't occur in a vacuum - nearly every optimization
transformation interacts with a dozen other transforms, sometimes with very
surprising (and usually counterproductive) results.

If you simply implement "book" optimizations, you'll find that they often
don't even work without some considerable re-engineering from the bottom up.
Many book optimizations make the code slower. And then there are the myriad of
optimizations that make code faster on one CPU and slower on the next release
of that CPU.

If you think that compiler optimizer writers are holding out on you, they
aren't. It's a bit of an arcane art, like samurai sword making technique.

~~~
evincarofautumn
Of course. I have no problem with generic, implicit optimisation. However,
people often need to optimise further, manually. Without good language
support, they start coding to a particular implementation: using less-than-
portable intrinsics, or worse, trying to trigger heuristics that produce the
optimisations they actually want.

------
RiotTony
Hey everyone, I'm the author of this article and I'm glad you've found it
interesting. I'll be keeping an eye on this thread, so if you have any
questions or comments I'll address them as soon as I can. I can already see
some awesome questions here - looking forward to the discussion.

~~~
josephg
Why scan the table of precomputed values? It seems like the code would be both
cleaner and faster like this:

    
    
      class AnimatedVariable {
        int numValues;
        std::vector<float> values;
        // ...
      }
    

Then:

    
    
      if (!mPrecomputed) {
        float idx = time * numValues;
        float before = values[idx], after = values[idx+1];
        return lerp(before, after, idx - (int)idx);
      }
    

I guess there's a bit of float -> int coercion going on there, but it
shouldn't be too bad.

~~~
RiotTony
Because we are interpolating between keys which aren't evenly distributed in
time. What you have there is pretty much what we do when looking up the
precomputed values from the table.

------
885895
>In our case we output the profile buffer to a file and read that into the
visualization tool which is conveniently built into Chrome. (You can find more
information about the tracing tool here and you can try it out by typing
“chrome://tracing/” into your Chrome browser. It is designed for web page
profiling, but the format of the input profile data is a simple json format
that can be easily constructed from your own data.)

Clever! Never heard of doing that but it makes sense.

~~~
Drdrdrq
Another term for these profiling charts in Chrome is flame charts, you might
be able to find even more tools by it.

~~~
cbab
Yup, basically Chrome is using an inverted flame graph (See [1] for additional
infos and tools).

[1] -
[https://github.com/brendangregg/FlameGraph](https://github.com/brendangregg/FlameGraph)

------
spawndog
Hi all,

I work with Tony the author of the article and answer (or find someone to
answer) any league questions you might have. Tony will be most likely be
online later in the day as he works remotely with us from Australia.

~~~
lunchTime42
Could the order of condition-statements-machine-code (as in the case handling
code)e.g. in the particle code be made rearranging according to in-game-heat-
counting?

~~~
RiotTony
You _could_ , but I doubt it would have much of an effect on performance.
Modern CPUs are ridiculously good at looking ahead and executing paths pre-
emptively, meaning that branching is far less of an issue. On the older
consoles, branching was a big issue, so that would have helped there.

------
mmanfrin
This is an interesting article, but Riot hasn't really earned any trust of
mine at all as it comes to code quality; for a while they couldn't show the
damage output of a spell because it caused the user's other summoner spell to
go on cooldown for 15 minutes[1] when they tried.

[1]
([https://www.reddit.com/r/leagueoflegends/comments/2hvukl/smi...](https://www.reddit.com/r/leagueoflegends/comments/2hvukl/smite_damage_should_be_shown_on_the_icon/))

~~~
bpicolo
"Its defects do not reflect issues with our code base (though there are many),
but rather my own hacky implementation."

Every code base has tech debt. You can't predict the requirements of the
future, and even if you could, trying to account for them means you never
release your product.

~~~
debacle
Riot's code base has a massive amount of technical debt, to a point where a
rewrite is likely the best choice because of past technology decisions.

~~~
ajkjk
A rewrite would murder them. I'm not going to link that article everyone links
about "never rewriting your code", because I don't think it's got the argument
right, but I strongly feel that if they tried to rewrite a system as complex
as theirs, they would either a) never finish or b) stop developing the game
and, by the time they finished their rewrite, have no customers left.

Anyway, it would end up being called a sequel.

~~~
debacle
Not having a well-written client is murdering them. Sometimes the hard way is
the best way.

~~~
kmkemp
No, it isn't.

They have the most popular video game of all time and you think that a poorly
written client is killing them? It has had some problems over the years that
are annoying to users (and frankly embarrassing when compared to DOTA 2), but
at the end of the day the quality of the client is insignificant to most
players compared to the fun-factor of the game itself, as proven by their
unprecedented success.

------
debacle
Dota 2 has custom games now. Maybe they can write the new client in Hammer.

------
Nemo157
Seems they don't want anyone using PIA to access their blog... Tried
reconnecting and got denied again, had to switch endpoint country to actually
get access.

> Error 1008 Access denied. The owner of this website
> (engineering.riotgames.com) has banned your IP address (108.61.57.217).

> Error 1008 Access denied. The owner of this website
> (engineering.riotgames.com) has banned your IP address (108.61.13.45).

~~~
jdmichal
Or that's the end effect of having been attacked from those IP addresses,
which I'm assuming are not unique to the user.

------
abledon
p.s. The world finals of the e-sports game 'League of Legends' made by this
company is happening this weekend.

Last year's event generated more global viewers than the NBA final.

------
a3voices
The biggest optimization would be to change their programming language.

~~~
to3m
To...?

~~~
christianmann
Lisp, clearly. /s

~~~
Roodgorf
Real Optimizers use Fortran.

