4 ms·
... I never meant to imply that performance was the reason for the switch. We've had a track record of technologies which: 1) Automated things (reliving progr
by woofie11 6y ago
... I never meant to imply that performance was the reason for the switch.
We've had a track record of technologies which:
1) Automated things (reliving programmers from thinking about stuff)
2) Were expected to make stuff slower
3) In reality, sped stuff up, at least in the typical case, once algorithms got smart
That's true for interpreted/dynamic languages, automated memory management/garbage collection, managed runtimes of different sorts, high-level descriptive languages like SQL, etc.
Sometimes, it took a lot of time to figure out how to do this. Interpreters started out an order-of-magnitude or more slower than compilers. It took until we had bytecode+JIT that performance roughly lined up. Then, we started doing profiling / optimization based on data about what the program was actually doing, and potentially aligning compilation to the individual users' hardware, things suddenly got a smidgeon faster than static compilers.
There is something really odd to me about the whole async thing with Python. Writing async code in Python is super-manual, and I'm constantly making decisions which ought to be abstracted away for me, and where changing the decisions later is super-expensive. I'd like to write.
- lultimouomo 6y ago> That's true for interpreted/dynamic languages, automated memory management/garbage collection, managed runtimes of different sorts, high-level descriptive languages like SQL, etc. Of the things you mention, I agree on SQL, and "managed runtimes" is generic enough that I cannot really judge. I'm thoughroghly unconvinced about the rest being faster than the alternatives (and that's why you don't see many SQL servers written in interpreted languages with garbage collection).
- woofie11 6y agoWell, I think you missed part of what I said: "at least in the typical case" (which is fair -- it was a bit hidden in there) There's a big difference between normal code and hand-tweaked optimized code. SQL servers are extremely tuned, performant code. Short of hand-written assembly tuned to the metal, little beats hand-optimized C. I was talking about normal apps. If I'm writing a generic database-backed web app, a machine learning system, or a video game. Most of those, when written in C, are finished once they work, or at the very most have some very basic, minimal profiling / optimization. For most code: 1) Expressing that in a high-level system will typically give better performance than if I write it in a low-level system for V0, the stage I first get to working code (before I've profiled or optimized much). At this stage, the automated systems do better than most programmers do, at least without incredible time investments. 2) I'll be able to do algorithmic optimizations much more quickly in a high-level programming language than in C. With a reasonably time-bounded investment in time, my high-level code tends to be faster than my low-level code -- I'll have the big-O level optimizations finished in a fraction of the time, so I can do more of them. 3) My low-level code gets to be faster once I get into a very high level of hand-optimization and analysis. Or in other words, I can design memory management better than the automated stuff, but my get-the-stuff-working level of memory management is no longer better than the automated stuff. I can design data structures and algorithms better than PostgreSQL specific to my use case, but those won't be the first ones I write (and in most cases, they'll be good enough, so I won't bother improving them). Etc.
- jfkebwjsbx 6y agoI am sorry to be blunt, but that sounds like a PR statement filled with nonsense. > If I'm writing a generic database-backed web app If you are writing a system where performance does not matter, then performance does not matter. > a machine learning system or a video game. Most of those, when written in C, are finished once they work, or at the very most have some very basic, minimal profiling / optimization. Wait, what? ML engine backends and high-level descriptions, and video games are some of the most heavily tuned and optimized systems in existence. > At this stage, the automated systems do better than most programmers do, at least without incredible time investments. General-purpose JIT languages are so far from being an actual high-level declarative model of computation that the JIT compiler cannot perform any kind of magic of the kind you are describing. Even actual declarative, optimizable models such as SQL or Prolog require careful thinking and tuning all the time to make the optimizer do what you want. > 2) I'll be able to do algorithmic optimizations much more quickly in a high-level programming language than in C. C is not the only low-level AOT language. C is intentionally a tiny language with a tiny standard library. Take a look at C++, D, Rust, Zig and others. In those, changing a data structure or algorithm is as easy as in your usual JIT one like C#, Java, Python, etc. > 3) My low-level code gets to be faster once I get into a very high level of hand-optimization and analysis. You seem to be implying that a low-level language disallows you from properly designing your application. Nonsense. > I can design memory management better than the automated stuff, but my get-the-stuff-working level of memory management is no longer better than the automated stuff You seem to believe low-level programming looks like C kernel code of the kind of a college assignment.
- woofie11 6y ago> If you are writing a system where performance does not matter, then performance does not matter. It's not binary. Performance always matters, but there are different levels of value to that performance. Writing hand-tweaked assembly code is rarely a good point on the ROI curve. > Wait, what? ML engine backends and high-level descriptions, and video games are some of the most heavily tuned and optimized systems in existence. Indeed they are. And the major language most machine learning researchers use is Python. There is highly-optimized vector code behind the scenes, which is then orchestrated and controlled by tool chains like PyTorch and Python. > Take a look at C++, D, Rust, Zig and others. In those, changing a data structure or algorithm is as easy as in your usual JIT one like C#, Java, Python, etc. I used to think that too before I spent years doing functional programming. I was an incredible C++ hacker, and really prided myself on being able to implement things like highly-optimized numerical code with templates. I understood every nook and cranny of the massive language. It actually took a few years before my code in Lisp, Scheme, JavaScript, and Python stopped being structured like C++. You putting "Python" and "Java" in the same sentence shows this isn't a process you've gone through yet. Java has roughly the same limitations as C and C++. Python and JavaScript, in contrast, can be used as a Lisp. I'd recommend working through SICP. > You seem to be implying that a low-level language disallows you from properly designing your application. Nonsense. Okay: Here's a challenge for you. In Scheme, I can write a program where I: 1) Write the Lagrangian, as a normal Scheme function. (one line of code) 2) Take a derivative of that, symbolically. (it passes in symbols like 'x and 'y for the parameters). I get back a Scheme function. If I pretty-print that function, I get an equation render in LaTeX 3) Compile the resulting function into optimized native code 4) Run it through an optimized numeric integrator. This is all around 40 lines of code in MIT-Scheme. Oh, and on step 1, I can reuse functions you wrote in Scheme, without you being aware they would ever be symbolically manipulated or compiled. If you'd like to see how this works in Scheme, you can look here: https://mitpress.mit.edu/sites/default/files/titles/content/sicm_edition_2/book.html https://mitpress.mit.edu/sites/default/files/titles/content/... That requires being able to duck type, introspect code, have closures, GC, and all sorts of other things which are simply not reasonably expressible in C++ (at least without first building a Lisp in C++, and having everything written in that DSL). The MIT-Scheme compiler isn't as efficient as a good C++ compiler, so you lose maybe 10-30% performance there. And all you get back is a couple of orders of magnitude for (1) being able to symbolically convert a high-level expression of a dynamic system to the equations of motion suitable for numerical integration (2) compile that into native code. (and yes, I understand C++11 kinda-added closures)
- jfkebwjsbx 6y ago> In reality, sped stuff up ... That's true for interpreted/dynamic languages, automated memory management/garbage collection, managed runtimes of different sorts, high-level descriptive languages like SQL, etc. None of that is true. Even SQL modeling declarative work in the form of queries requires significant tuning all the time. The rest of the list is egregious. > things suddenly got a smidgeon faster than static compilers. No, they did not.
- mpweiher 6y ago> It took until we had bytecode+JIT that performance roughly lined up. It really didn't. Yes, in highly specialized benchmark situations, JITs sometimes manage to outperform AOT compilers, but not in the general case, where they usually lag significantly. I wrote a somewhat lengthy piece about this, Jitterdämmerung: https://blog.metaobject.com/2015/10/jitterdammerung.html https://blog.metaobject.com/2015/10/jitterdammerung.html Discussed at the time: https://news.ycombinator.com/item?id=10344601 https://news.ycombinator.com/item?id=10344601
- woofie11 6y agoWell, if you wanna go that route, in the general case, code will be structured differently. On one side, you have duck typing, closures, automated memory management, and the ability to dynamically modify code. On the other side, you don't. That linguistic flexibility often leads to big-O level improvements in performance which aren't well-captured in microscopic benchmarks. If the question is whether GC will beat malloc/free when translating C code into a JIT language, then yes, it will. If the question is whether malloc/free will beat code written assuming memory will get garbage collect, it becomes more complex.
- mpweiher 6y agoObjective-C has duck typing (if you want), closures, automated memory management and the ability to dynamically modify code. And is AOT compiled. GC can only "beat" malloc/free if it has several times the memory available, and usually also only if the malloc/free code is hopelessly naive. And you've got the micro-benchmark / real-world thing backward: it is JITs that sometimes do really well on microbenchmarks but invariably perform markedly worse in the real world. I talk about this at length in my article (see above).