5 ms·
>I find premature optimization to be far, far more wasteful of money and human energy than wasted CPU cycles. I would argue this always depends upon what you'r
by devwastaken 10y ago
>I find premature optimization to be far, far more wasteful of money and human energy than wasted CPU cycles.
I would argue this always depends upon what you're doing. For example, in webdev, the culture of prototype fast and break things fast is very abundant, and makes sense when you're just trying to figure out if what you want done is even possible. However, there are many times where you /do/ have to consider the performance impact, because with it, what you're making isn't going to be nice to use.
By dogmatic, I think they meant individuals who will actually argue that '100ms' loop times are 'tiny' and shouldn't be a problem. They don't get the concept that its just one small part of your code, and the rest of it combined can make an entire process take up to 5-10 seconds to do something that should be in a blink or two. Learning about optimization is a part of learning programming, and knowing when to use it. The problem is when you don't know it, and fumble around trying to do so when you've got much bigger problems further ahead.
I ran into this problem a lot with image filtering and working with Canvas's to build an image editor. I talked with some communities about the Uint32Array implimentation in chrome and other browsers and how some of the ES6 goodies, like 'let', are actually bad practice when you start to get into image filtering, because just iterating over all the pixels in an image by using "for(let i=0;i< pixel.length;i++){}" is 3x slower than using var, causing just a single full loop to be 80-120ms on a good computer.
TypeScript compiles down to var, though, so its less of a problem there, but I met a lot of resistance in that statement in general, even though its true, because there's a lot of dogmatism in programming. At the end of the day I'd rather learn and teach good practices and not tell people they're pre-optimizing unless they really don't know much about what they're working with.
- dahart 10y ago> some of the ES6 goodies, like 'let', are actually bad practice... 3x slower than using var This is good to know! I suspected, but never verified. I assume this will get fixed over time, since 'let' is brand new. But JavaScript in general isn't well suited to image filtering, right? Certainly worth using, if at all possible, either CSS filtering or WebGL. Either of those will be much faster. Depending on what you're doing, some complex filtering operations will even be faster to upload to a back-end, process, and download the result. :P Is WebGL something you avoided because it won't work for you, or something you avoided because it's more costly development wise? Hey overall, I agree with everything you say, and I'm still comfortable saying, dogmatically, never optimize prematurely. What that means to me is don't do engineering for problems you don't know you have. If you're not sure, then you don't know. If you're doing filtering, and napkin math proves in advance that you can't beat 5fps and your requirements call for 15 fps, then you do know. In my mind this even fits with startups, because a startup's mission is to find the product and market, to figure out what's possible and then execute on it. So ultimately I agree 100% it always depends on what you're doing, my additional caveat is always know what you're doing. :)
- devwastaken 10y ago>either CSS filtering or WebGL CSS only has basic filters, and WebGL is only possible for per-pixel manipulation, such as brightness or contrast. This is because WebGL is just shaders, and half of shaders are per-pixel, along with some other fun things you can use with multiple buffers, but you can't actually get /back/ the processed data even if you got all the pixels into a single loop. With WebGL 2, this may be different due to some new buffer types, but I don't think its made for it. Any time you do an algorithm that is dependent upon surrounding pixels, such as dithering, you're stuck with JS. https://tools.czaux.com/space-pixels/ https://tools.czaux.com/space-pixels/ Here's an example of in-browser dithering to a fixed palette set that works pretty well, using RGBQuant modified with alpha support. The overall canvas uses FabricJS for manipulation.
- dahart 10y ago> but you can't actually get /back/ the processed data even if you got all the pixels into a single loop Oh if you need the pixels back, you can certainly get them using glReadPixels(). It's a bit expensive in WebGL land, though it is much less expensive than looping over pixels using JS. And often there are ways to get around needing the pixels back, depending on what you're doing. You can also do loads of non per-pixel tricks, including filters that need the surround, using multiple passes and clever shaders, you are not as limited with WebGL 1 as you think. https://5013.es/toys/dithering/ https://5013.es/toys/dithering/ https://www.shadertoy.com/view/MslGR8 https://www.shadertoy.com/view/MslGR8 This is what I'm talking about, you have to slice your program differently if you optimize it. Your high level structure and outermost loops will look different if you use WebGL instead of JS. And yes WebGL 2 is even better. But, this is all much trickier than writing your straightforward loops in JS. That's the price you pay for performance, your architecture will be kinda crazy if you do it in WebGL, and it will not be easy to go back if you discover you optimized for the wrong thing.
- devwastaken 10y agoRandom-order dithering can be done in WebGL, but they are of poor quality. I am talking about error-diffusion dithering, where you are reading and writing pixels, and then re-reading those modified pixels that change the rest of the pixels. In WebGL, you can read the pixels of the image, but you cannot modify and read. You are returning the actual pixel you have modified, which is what glReadPixels() returns. You could use webgl, but you'd have to use glReadPixels() for every pixel modified so that the next pixel knows the new data.
- dahart 10y ago> ES6 goodies, like 'let', are actually bad practice... BTW, this is a really good example of why people like to avoid premature optimization. Performance oriented code frequently has to break all the rules, it often goes against all "best practices" for code that isn't performance critical. If you do it too early, you will wreck your codebase's ability to deal with 1- non performance critical code and 2- other performance issues than the one you solved. If you make it a rule to avoid using 'let' everywhere, then you lose the safety mechanism of block scope variables, something that a lot of people agree is a good idea. It's very easy when you find out that let is 3x slower to stop using let, but then if you do that you're prematurely optimizing everything. And if you don't do it, everything you write is a little slower than it could be, and that will nag at you. Functional programming is another good example of what many many people consider a good idea for code safety, and yet it is frequently abysmal for performance. Just to use another JavaScript example... using map() has historically been about 10x slower than using a for loop. The singularly smartest engineer I know, who's now managing a huge team at NVIDIA, said to me that engineering for features is a solved problem, but engineering for performance is an unsolved problem. We know how to do class hierarchies and architecture and pub-sub systems to make a 10M LOC application manageable. We don't know how to write high performance code on that scale.
- devwastaken 10y ago>If you make it a rule to avoid using 'let' everywhere, then you lose the safety mechanism of block scope variables, something that a lot of people agree is a good idea. Which is why I said its bad practice in specific cases, currently. 2.5 Million iterations is a use case, not a general rule. Programming is complicated, and as such you should know not to make the assumption that a use case isn't going to apply everywhere. Rather, you can say that microseconds of performance difference aren't a good reason to not use let, unless, you're not using something that compiles down to var, and you're going into the millions of iterations. But, the point I was trying to make is that even when you talk about performance problems, devs jump the gun to 'pre-optimization', partially because they themselves don't know how well code performs, and partially because of misapplied dogmatism.
- dTal 10y ago
- the8472 10y ago> because just iterating over all the pixels in an image by using "for(let i=0;i< pixel.length;i++){}" is 3x slower than using var, causing just a single full loop to be 80-120ms on a good computer. That is an implementation detail. Of specific chrome versions. That does not make let itself bad practice. In principle it should be significantly easier to optimize for a compiler because its more limited scope. So in the long run or possibly on other browsers it is likely best practice. Putting transients before long-term behavior leads to urban programming myths and legacy baggage. In fact in some jsperf benchmarks on chromium let happens to be faster for me.
- devwastaken 10y ago>Putting transients before long-term behavior leads to urban programming myths and legacy baggage. Not when the problems still exist. When they stop existing, sure, but the statement generally goes along with how some parts of ES6 are not well optimized yet. Over time, they should be optimized, but I cannot design something for an event that hasn't happened yet and cannot be tested.
- lederhosen 10y agoYou are doing it wrong. let is better than var (in every way), so you should never ever use var. Of course you can design for the future. Designing for the future is using let and transpile to a dialect that is used by most browsers today.
- devwastaken 10y ago>let is better than var (in every way), so you should never ever use var. Not in the case I presented. let has benefits, but that does not mean its 'better in every way'. Again, dogmatism. Granted, the case I give is many, many iterations, it still is a problem if you're doing image filtering.