5 ms·
As cgabios noted below low-level code obduscates intended behaviour. Ever tried to write a C optimizer? A trivial example is a for loop vs map -- the former h
by stass 11y ago
As cgabios noted below low-level code obduscates intended behaviour. Ever tried to write a C optimizer? A trivial example is a for loop vs map -- the former has inherent ordering semantics and compiler does not have any way of knowing if this behavior needs to be preserved, while the latter just tells that a particular operation needs to be applied to each element so compiler is free to reorder/parallelize/etc. There are much worse situations that arise from low-level language having to preserve the underlying machine memory semantics (that is one of the reasons why it is hard to compile low level languages like C or C++ to e.g. Javascript. Compiling x86 assembly would reuire a full machine emulation).
This is discussed in detail in most introductory CS books if you would like to learn more.
- fleitz 11y agoIn asm you write loops because they are easy, map is hard (and generally slow because it's a lot more code.) ASM derives performance from specialization, ASM asks, how often is this code ACTUALLY going to run on another architecture, OS, etc? And then gains performance by not supporting those things via abstractions, etc. Throw away your CS textbook and run benchmarks, reality dictates theory, not vice versa.
- stass 11y agoSpecialization is what compilers do really well. :) Humans -- not so much.
- kibibu 11y agoI'll give you a counter example. GPU drivers spend a lot of time trying to optimize beneath their corresponding high-level API. This more-or-less equivalent to compiling GPU machine code on the fly based on GPU configuration - that is, very much like optimizing a high-level language. If everything goes smoothly, the drivers can do a pretty good job of optimizing everything. However, if you deviate slightly from the "fast path", the whole thing falls off a performance cliff, and because it's a high level language with a secret black-box optimizer behind it you're actually worse off investigating performance issues than you would be if you'd just written things at a lower level. Not coincidently, graphics APIs are moving to lower levels precisely to remove the complexity from the compiler, increasing transparency and making things more predictable. Now you might suggest that a "sufficiently advanced compiler" wouldn't do that, but such a thing is a fiction. In practice, the compiler is never sufficiently advanced to optimize in all cases effectively. --- Consider Javascript, where exactly the same thing happens. Your definition of a "high level language" may not include JS, but it's hard to argue it's not higher than ASM. Modern day JS engines do a pretty good job of optimizing code JIT. However, you make some innocuous code change and suddenly your function is running in the interpreter instead of being optimized (see https://github.com/GoogleChrome/devtools-docs/issues/53 https://github.com/GoogleChrome/devtools-docs/issues/53 for examples) If you were using a lower-level language, your chances of falling off mysterious performance cliffs is significantly reduced. Further, you have the capacity to do low level optimizations that your compiler literally cannot do. So what if your high level language can now do parallel-maps, if it ignores cache thrashing, or hits load-hit-stores or any one of myriad actual performance holes that real code can fall into? Or you add a field to the objects you're iterating over and the parallel map implementation hits a weird memory stride and perf drops through the floor. How do you even debug something like this in a high level language where all you see is "map()"? --- I also think your compiling-ASM-to-JS example is a bit of a strawman, FWIW. The parent was talking about how high-level languages yield higher performance than lower-level ones, not about the portability or transpilability of ASM->JS. (A "suitably advanced transpiler" would handle this problem perfectly anyway)