lexyeevee

troublesome fox girl

hello i like to make video games and stuff and also have a good time on the computer. look @ my pinned for some of the video games and things. sometimes i am horny on @squishfox



lexyeevee
@lexyeevee

is a process, not a stat, not even a progress bar

please can the Gamers stop saying things have "bad optimization" or whatever. i don't know how to kindly explain to you that the way it sounds lands squarely on a spectrum between clueless and jackass. consider the following:

  1. it is a MIRACLE that video games work. like, at all. i make video games and i can hardly believe they exist. and that's before you even get to the graphics!

    here, i'll give you all the vertex coordinates of ten thousand objects in 3D space. tell me which ones are touching. you have: 0.005 seconds. good luck

  2. making something faster while behaving the same is hard. it is really hard. it is really really fucking hard. it is one of the hardest things. if you're lucky there's some obvious low-hanging fruit that gets you far enough. beyond that it is a niche so specialized that it has no name, performed by 1 witch at your studio that no one's sure they've actually met in person, who disappears for three weeks only to reveal they've improved load times by 9% by forking ext4 to store entries in alphabetical order, whatever the fuck that even means, while the rest of you are desperately scouring stackoverflow for something bozotic like whether double-quotes are "faster than" single-quotes

  3. there is no such thing as "fast". there is only "faster", and "fast enough". you don't just keep going until you have Fully Optimized The Code because that is not a real thing. you plunk away at one thing at a time and watch your update and render times drop by microseconds, sometimes unsure whether you've even made a difference because it's drowned out by noise. maybe you made things slightly worse, even. maybe better on one platform but worse on another. cross your fingers i guess. how long until we're supposed to ship, again?

this just really grates at me because like

"it's slow for me" is a factual observation. even "it's slow for everyone" is a factual observation. "it has poor performance" is still a factual observation. "it's fucking unplayable", "runs like ass", sure

but "it's badly optimized" is a value judgement of skilled work that someone did (or lacked time/expertise to do) on code you have never read. it seems to have come out of the same vortex that produces insights like "[game] was made with the unity engine, which is why [non sequitur]" from people who are inexplicably compelled to talk about the nuts and bolts despite having never seen either a nut or bolt themselves

you can just, have opinions on video games. you don't need to try to fake sounding like maybe a programmer


DecayWTF
@DecayWTF

turning a big Dial called "Optimization" and constantly looking back to see how much i can set it to Bad because i hate gamers, especially, man's


lexyeevee
@lexyeevee

if i made a AAA video game i would simply optimize it more. i would optimize it all the way, in fact. simply do maximum optimization. stupid devs, why do they need me to tell them these basic things


drmelon
@drmelon

i absolutely broadly agree with all the points made here - the outside perception of "lazy devs" is both harmful and inaccurate.
but my full time job is optimization of games for difficult platforms and there is just a baseline educational failure in a lot of cases as to why certain practices will absolutely tank performance. i have seen a surprising number of very mature AAA studios fail to account for a relatively easy to understand principle, once it is known; don't make the computer do more work than it has to.
i see things like repeatedly recalculating expensive transformations each frame, when the thing in question neither moves nor changes each frame, or creating and destroying UI elements instead of making them simply hide and reappear. and these account for a huge bulk of early gains on performance, as long as they are kept in mind from early on in the project.
the industry does not and has never adequately trained people to understand these things intuitively, because our industry has a knowledge sharing problem. many simple, repeatable techniques are hidden from public knowledge under the misguided principle that a studio needs a "secret sauce" to succeed, when really all they are doing is simultaneously reinventing the wheel. seniors burn out, juniors get churned into crunch, and nobody learns the simple techniques that can make their games run smoothly and easily.


lexyeevee
@lexyeevee

overnight someone else also objected that i made optimization sound like something only the Chosen Ones can do. but i think optimization is more a form of bugfixing or auditing, something you do on existing work, whereas "write it so it's not unnecessarily slow in the first place" is a different kind of problem entirely.

and i think it's something that's just kind of hard to learn. it's easy enough to see if code works, because you can just run it and see if it does the thing you wanted. it's harder to see if code "is fast" in some sense, especially when even the "slow" version is so fast it's indistinguishable from noise. a particular pattern may never show up in a profile, but still add up if it's done in multiple places. but it also may not! "you should avoid this, because it might be a problem, later, sometimes, unless it isn't" is somewhat less compelling than "here's how to make your guy fire a gun".

and like, i wouldn't say i actively think about performance when writing code. instead i have a system of internal alarm bells that go off whenever i find myself writing a linear scan, nested loop, basically anything that examines the world state, something complicated per-frame that is likely to have the same result every time, etc. i have a whole series of "what if"s that float to the surface. what if this list is excessively long? can that happen? what if one block in the blockmap accumulates a great many actors? do i want to proactively handle that? what if the player is too far away? what if there is no player? what are my assumptions, and what happens if they are violated?

(sometimes the answer is even "that seems highly unlikely and it's not worth the time to worry about"!)

and that's not easy to pick up. it's not like "a while loop runs until the condition is false" where you read it and now you know it. there's no exhaustive list of all the things you might do that will make the computer spin its wheels unnecessarily, which you can simply memorize and keep in your working memory at all times. you have to pick them up one at a time and develop a sense for the kind of thing to look out for. it comes from experience, but not from writing code — from listening to other people talk about it. and if you don't have that sense yet then i imagine it feels like you're expected to look at every line of code and think about "hmm do i need to do this here", which just sounds incredibly tedious and unrewarding

and even if you're pretty good about it, it's still often counterintuitive, and you might miss something at any time. sure, of course i want to compute this transformation every frame. that's what i do for every other entity, right? do i even know for sure this thing never moves? does it move now, but we changed it later to be static? does it move conditionally?

hell, i've shipped a fucking quadratic draw loop that was obscured by several layers of function calls, thanks to a refactor that wasn't quite finished. i never noticed because my computer is Fast Enough; someone with a slower computer told me about it.

also my experience with bay area tech is that tech companies fight over devs who just got out of college, for some reason. but those are exactly the people who are the least likely to have developed intuitions like this. (ok i guess someone who's only been self-teaching a couple years is less likely but you know.) and it sounds like a similar thing happens in big-name gamedev too. alas

anyway i would say

  • "don't do an expensive thing every frame if you don't need to" isn't optimization so much as Just Programming. it's not a wizard-only skill, but it's hard in its own way, since it's about learning to catch yourself in the process of writing something that (a) feels natural and (b) would work!

  • "find where someone already did an expensive thing every frame when they didn't need to" is optimization and is vastly more annoying. especially if you think you've found such a place and you refactor it and it makes precisely zero difference. that's why optimization is hard: often you are searching a haystack for a strand of hay that looks slower than the others. what does that even mean


You must log in to comment.

in reply to @lexyeevee's post:

Also yes to the witch. Everyone's been fighting to pare cycles from the inner game loop for three weeks and they turn up in awful shape at standup one morning having not slept in four days. The new routine is a bunch of raw opcodes in a byte array that, insanely, means the same thing in armhf as it does in x64. It is 50% faster but no one understands how it works, them included. The CR has the original assembly but it doesn't assemble to the same set of opcodes in from either the ARM or Intel assembly source. It passed all the tests however. They do not turn up at any more team meetings. A month after launch you find out they moved to Alaska.

you don't just keep going until you have Fully Optimized The Code because that is not a real thing.

Wanted to add to this, because optimizing graphics is currently my job, and explaining things like this to my coworkers is therefore also my job.

Doing an optimization is several kinds of hard. Doing a "full optimization" is several kinds of impossible, coupled with several kinds of not well defined.

I can make benchmarks that try to represent real-world stress cases such that "code that performs well on these benchmarks will seem fast to users". Inevitably some of the assumptions I made will turn out to have been wrong. I'll have missed some rare but important real-world case and have to make updates to the benchmarks.

But let's suppose my assumptions are solid, and that I can use the benchmarks as ground truth. There's still a sense in which "optimization" is not well defined. Doing well on one test-case in one execution environment doesn't guarantee doing well on all of them. There's room in the design space to make tradeoffs, like "what if I did some extra computation to prune some potentially unneeded branches? It would make some cases faster and others slower". If I want some way to compare apples and oranges, I could make up a composite score that flattens all the results into one metric. Again, I'd be making assumptions that are definitely arbitrary and probably wrong.

But let's suppose that I've made the "right" assumptions (whatever that means). There's now some sense in which code could be said to be "optimal" with respect to that metric. Once I've fixed a scoring system, there exists some implementation out there that gets the best score. Of course, I still don't know what the best score is, and finding out is an undecidable problem.

I am currently involved in a performance project (not games, just boring business software), and the question of “are we done?” is of course obviously ridiculous, but even the question of “is it even any faster on anyone’s computer other than my own, in any situation outside of this synthetic test case?” is soooooooo much harder to answer than it seems like it should be

This reminds me of the old days when I had to regularly engage with programmers who had big-O Opinions on the relative "efficiency" of different programming languages. Because yes, the problem with your code is definitely that you're running on top of a virtual machine and not the fact that your data is stored with no plan of how to connect related elements, and you should definitely rewrite the whole thing in assembly language to trip half a percent off the runtime, assuming that it doesn't produce so much code that you have more cache misses...

This is a fair criticism and I will be altering my language accordingly.

Except with one exception: "Final Fantasy XIV 1.0 was badly optimized" is a factual statement because of shit like the flowerpot that had more polygons than a player character.

in reply to @lexyeevee's post:

knowing gamers, i would bet money that someone somewhere up the chain in the game of idiot telephone, someone vaguely knew about the -O flags on C compilers and still literally thinks that optimization is just "run it on the biggest -O".

in reply to @lexyeevee's post:

I think performance intuitions are specific to different types of programming, which adds another level of difficulty. I'm not sure computer science degrees tend to prepare students for the kind of optimization specific to games, for both good and bad reasons, so I suspect a lot of game developers have to learn on the job. (I suspect the use of engines like Unity and Unreal don't help, but I don't have the experience to say.) They also have to shift over time as hardware, OSes, interpreters, and compilers change.

One thing that I've struggled with doing game development is that I don't have the intuition for what my graphics card is capable of. Like it's hard to make the call whether I'm in a position where I'm trying to draw too many sprites of that resolution or if I've just chosen the wrong flag or something. Whereas if I'm doing data analysis I have a pretty good sense of how much data is Too Much and just won't fit in memory.

i suppose it comes down to whether or not programming education should include the use of a profiler along with the use of a debugger as kind of a standard learning outcome - instilling the practice of measuring what's slow and what's not will build that intuition quickly, and will also help course-correct when diving down a rabbit hole of red herring "optimizations"!

the tricky part is that you obviously think to reach for debugging tools when something goes wrong, but you may not even notice something goes slow (or just slower than it could be), especially on rinky-dink beginner projects

i guess an added wrinkle is that in a lot of applications, an extra 1ms is nothing. in gamedev it is A Problem

and then some people get weird ideas about it, like that website where people write little microbenchmarks to work out whether const or let is faster (?????)

I think part of why this post doesn't really land for me is that the last big complaint I saw was. about the fact that Slay the Princess is vastly larger than it needs to be because all the audio is shipped as WAVs, which isn't something that would take a lot of arcane knowledge to fix.

and, sure, most people don't know the technical skill that goes into optimization and will never see the code. but optimization is all about the end result. i don't need to be a chef to say that a rubbery hamburger that's more carbon than meat was "badly cooked". ultimately I think 'badly optimized' and "shitty performance" mean the same thing. conversely, if I write the fancy clever algorithmic approach on the first go, I would say that's just as "optimized" as if I had written the slow approach first and changed it later.

similarly, I would describe a song where the creator didn't bother adjusting the volume on the individual instruments relative to each other as "mixed poorly" even though by definition they didn't mix it (or "mixed well" if it came out good)

a complaint that i often see that this does map onto is "spaghetti code"; code structure translates far less immediately onto things the user can see than performance choices (unless you have a mod API)

a burger is, necessarily, cooked, or it's not a burger. i think the thorn in my ass here is that you can write and ship code without ever thinking about performance at all, and it might be fast enough or it might not, but either way i don't think it really "has been optimized". that implies someone specifically took a look at it, surely. it's more like reading subpar prose and saying it's "poorly edited" — chances are it wasn't edited at all

shipping all wavs doesn't even surprise me. maybe that was easier for the sound folks and someone intended to convert them all once they were set in stone but forgot when other things came up. games are so big it's so easy for things to slip through the cracks. and sure it sucks for everyone when that happens. but "badly optimized" always reads to me like it's saying someone tried and fucked up, which is a fair bit different

eh i mean see my mixing example; i think we just use language differently here, and debates over language are rarely productive, so i think there's nothing more for either of us to say (i am saying this in a neutral manner, not like an anime character unsheathing her blade before the final duel)

but yeah i'm not surprised by it, i've used wavs in development. i was more pointing it out as an example of something that could get very significant gains with relatively little effort and where you can easily tell whether you've made progress

"Spaghetti code" annoys me far more than "badly optimised" because it has an actual meaning which is incredibly not relevant to gamers—the quality of the code that the people working for Game Freak or Bethesda write matters to them because bad practices now create technical debt which might impede their work down the line, but it does not make a blind bit of difference to your enjoyment of the game that VVVVVV uses a single giant switch statement or whatever.

Programmers might chafe at gamers using "optimisation" in ways that don't line up with their understanding of the term, but that's not really any different to physicists complaining about people using "speed" and "velocity" interchangeably; they're not talking your subdialect, and "optimisation" is I think somewhat meaningful within the confines of gamers talking to one another about games.