Hacker News new | ask | show | jobs
by ajross 3782 days ago
To be fair, GPU vendors sucked up a ton too.

But considering that optimized scalar code performance has moved, what, maybe 40% over the last two decades, I'm going to say "not much". Compilers are sexy, but they're very much a solved problem. If we were all forced to get by with the optimized performance we saw from GCC 2.7.2, I think we'd all survive. Most of us wouldn't even notice the change.

6 comments

I'd disagree. Classical compiler work is very mature, yes - and new progress in things like register allocation and backend IR-based optimization stuff is well trod ground.

But in the context of JIT compilers for dynamically typed languages, in particular the space involving runtime inferred hidden type models, there is a TON of work left on the table.

It hasn't been paid much attention to in academia, IMHO largley because of a historical perspective on optimizing dynamic languages as "not classy" work among language theorists. I hope that perspective changes over time.

> Compilers are sexy, but they're very much a solved problem.

Not for all of the other widely-used languages that still have incredibly simple interpreters. Think how much energy could have been saved if Ruby, Python, and PHP were all as fast as your average JS engine.

> Think how much energy could have been saved if Ruby, Python, and PHP

I would think we'd see even better improvements if developers would move towards statically typed languages as well.

Exactly. Ruby would probably have massive adoption with JS-like speed.
My implementation of Ruby, JRuby+Truffle, is as fast as V8

http://stefan-marr.de/downloads/crystal.html

Note that usually being "as fast as" a production JSVM means also proving that you can start up as fast as JSVMs do. Have you done this?
Search around for "Substrate VM". I see it referenced in some slide decks, and it's designed to make JVM startup much faster.

Here's an old slidedeck that talks about it: http://www.oracle.com/technetwork/java/jvmls2013wimmer-20140...

Wow thx for the reminder, I have forgotten about it already. I remember the promise of Truffle + Graal + Substrate VM.

My god can't believe it was 3 years ago i read about it on HN.

I know about it. I'm not concerned with future hypotheticals, but current actual measurements.

That's the currency I deal in.

There seem to be measurements in the slides I reference, so it wasn't exactly "future work". But of course it sucks that this work is not yet publicly available (AFAIK), probably due to not being 100% production ready yet. But I'm sure it's getting there.
Ruby has massive adoption, as do Python and Perl and PHP. Environments with objectively better performance like the JVM and .NET have not, in fact, done all that well comparatively in this environment (which is to say they've done fine too and achieved "massive" adoption, just not that much better than their slower competitors).

In fact, looking at the market as it stands right now I'd say that performance concerns are almost entirely uncorrelated with programming environment adoption.

Considering the massive speed improvements we have been seeing in Javascript, but also languages like Ruby, I'd say compilers is a solved problem for staticly compiled languages, but perhaps not as much for interpreted highly expressive languages.
Sort of. Lisp had a good combo of expressiveness and speed in the 80s, but it reached that point on the efficiency frontier by different techniques, like heavier use of macros. The newer techniques like trace compilation can make life even better, but the language design decisions in Ruby/Python/etc. that made that sort of thing necessary if you want speed, they didn't really pay for themselves from the perspective of smug Lisp weenies like me who were happy enough with our language and just wanted pragmatics like libraries.
Did you just call Javascript a "highly expressive" language? Really?!?
LOL! It is expressive though. It's got really powerful first-class functions. It's got classes. It's got prototypes. It's got generators. It's got other things that I don't even remember (but will probably have to learn, to implement them, make them fast, and then fix the bugs).

I actually think that the reason why JS is so odd is that it is so expressive. That tends to happen with kitchen sink languages like C++.

Relevant: "There are only two kinds of programming languages: those people always bitch about and those nobody uses."

ajross is right. People choose the languages they like regardless of performance.

JS perf is important to users though. Faster execution means fewer watts spent rendering and interacting with your favorite web page.

(Fun fact: B3's backend contains a machine description language that gets compiled to C++ code by a ruby script, opcode_generator.rb. We use Ruby a lot.)

Why didn't you use JavaScript for that purpose (in a similar vein to how LuaJIT uses Lua for dynasm)?
I'm not a big fan of self-hosting. I like that you can build JavaScriptCore without using JavaScriptCore.
I wasn't really referring to self hosting. I was wondering whether it made sense to write tools like JavaScriptCore's offlineasm in JavaScript rather than Ruby (as LuaJIT does by using Lua for its dynasm tool). The LuaJIT build process actually builds a cut down copy for Lua for the purposes of running dynasm, which is then used to build parts of LuaJIT.
Suppose that you are developing not to push this platform, but to simple do better on this platform. What does self-hosting gain you in that case?
Lately quite a few apps are saving energy by moving from Ruby/Python/PHP to Go.
And Go proves munificent's point: it doesn't have many compiler optimizations either. (This may change with the WIP SSA backend, but the point remains that Go gained huge popularity in spite of having a non-optimizing compiler.)
Yeah, more interesting is having them rediscovering Turbo Pascal compile speeds.

EDIT: I wonder why the positive effect to re-discovering that not all compilers need to be like C and C++ compile speeds and that it was once upon a time mainstream, is worthy of downvotes.

Can't critique this one: Go was an attempt to re-create the Oberon experience in modern setting with some additions from other languages. Rather than accidental re-discovery, getting Oberon (not Pascal) speed out of the compiler was an explicit design goal. One of few examples of modern IT really learning from the past.

Unfortunately, they didn't learn about the stuff between Oberon and 2007 that would've been nice to have in a modern, app language. ;)

It is not a critic, apparently it was understood as such.

The remark is tailored to those that think compiled languages can only be slow as C and C++ compilers, since they never used anything else, and then jump of joy when they use Go.

Yet if it wasn't for the VM detour of the last 20 years, that experience would probably be a current one, instead of being re-discovered.

For the curious (I am sure pjmlp is well aware of this) D and Go compile speeds are pretty neck and neck. DMD was faster, then Go caught on, not sure which one is faster now, depends on the nod. If I may add, D is a lot less impoverished than Go, although its coroutines story is not that strong.
Are you claiming Go runs at the speed of Ruby/Python/PHP etc? Because from what I read, migration to Go from above mentioned language led to lot of hardware / memory saving. I'd think Java can certainly be considered having highly optimized compiler / runtime. But it has almost same performance as Go and much higher memory usage compared to Go.

http://benchmarksgame.alioth.debian.org/u64q/go.html

> Are you claiming Go runs at the speed of Ruby/Python/PHP etc?

No. I'm claiming it doesn't perform anywhere near the level of optimization of GCC and LLVM.

> I'd think Java can certainly be considered having highly optimized compiler / runtime. But it has almost same performance as Go and much higher memory usage compared to Go.

I disagree with what seems to be your implication that compiler optimizations don't matter (and almost everyone else who works on compilers would also disagree), but I don't really want to turn this thread into a critique of the benchmarks game, so let's just leave it at that.

> … and much higher memory usage compared to Go.

Please don't jump to the conclusion that huge differences in the default memory allocation of tiny 100 line programs means there will be similar huge differences between ordinary large programs.

Notice that even for those tiny 100 line programs, the difference can be more like 2x when memory actually needs to allocated for the task.

"Compiler optimization" in this thread is referring to speeding up compilation time†, not runtime of generated code. Go produces fast code, but the go compiler does not generate that code particularly quickly.

† Which can be seen as a runtime cost for interpreter+JIT languages, but that's a different issue. We're talking time-to-steady-state when the interpreter is fed a file (which is something Javascript engine devs worry about a lot), not benchmark-speed-at-steady-state.

No, it's the opposite. The Go compiler generates medium quality code but compiles fast.
If Ruby, Python and PHP would suddenly disappear, even more effort and energy would have been saved.

    Compilers are sexy, but they're very much a solved problem.
This may be true for sequential languages, but is very much false for the compilation of concurrency and parallelism. It's basically not known how to do this well. Part of the problem is that CPU architectures with parallel features have not yet stabilised.

For sequential languages the problem has shifted: how can I get a performant compiler easily. The most interesting answer to this question is PyPy's meta-tracing, and that's work is from 2009, and far from played out.

> Most of us wouldn't even notice the change.

A 40% decrease in optimization is enough to drop framerates from 60fps to 30fps easily, so I'm pretty sure we would notice it.

> optimized scalar code performance has moved, what, maybe 40% over the last two decades

I'm not convinced. Raw single-thread number crunching performance is somewhere around _two to three fold_, clock-for-clock, on Intel x86, over that of 10-15 years ago. What methodology do you use to attribute only a fraction of those gains to language optimizers? And even if you are correct, why is it meaningful? Who is going to have invested energy in optimising the shit out of mundane codegen when hardware performance will have just come and stolen your thunder a few months later?

The problem we have now is that CPUs are gaining ever more complex behaviour, peculiarities, and sensitivities. I'd say compiler engineering is far from a "solved problem", even for statically-typed languages.

> The problem we have now is that CPUs are gaining ever more complex behaviour, peculiarities, and sensitivities.

With mainstream CPUs, exactly the opposite is happening. CPUs are getting more complex under the hood, but less sensitive to code quality. For example, a lot of the scheduling hazards in the P6 microarchitecture have been eliminated in subsequent iterations. Branch delay slots are a thing of the distant past, so are pipeline bubbles for taken branches, indirect branch prediction is extremely capable, even the penalty on unaligned accesses is minimal.

Well, sure, but SIMD more than compensates for all of that, given how hard autovectorization is. In fact, I think with things like AVX and NEON becoming ubiquitous, you can get more benefit out of writing in assembly (or intrinsics) than any time I can think of in the past 10 years.
> Compilers are sexy, but they're very much a solved problem

No they're not, and won't be for long (ever?). However it does not matter because they are "good enough".

Compilers are driven by heuristics which provide "reasonable" results in most cases for common architectures. But they still leave a lot on the table. Compiler writers have to trade compile-time with execution-time. Now we're not talking about an order of magnitude, but rather ~20%-30% in some workloads. When it matters (I guess for people like Google/Facebook/Amazon/... it translates in electricity bill and a number of racks to add to the datacenter) people may have to get down to the assembly level for a very small (and hot) part of the program.