Hacker News new | ask | show | jobs
by alberth 3779 days ago
>> "tl;dr: B3 will replace LLVM in the FTL JIT of webkit. LLVM isn't performing fast enough for JIT mainly because it's so memory hungry and misses optimisations that depend on javascript semantics. They got an around 5x compile time reduction and from 0% up to around 10% performance boost in general." [1]

Is this a knock on LLVM then?

I wonder then specifically if this brings to light any concerns over Swift (another dynamic language, and was created by the same person who created LLVM as well). [2]

Seems weird that the original creator of LLVM was able to make a dynamic language such as Swift - without any problems.

[1] https://news.ycombinator.com/item?id=11105231

[2] http://nondot.org/sabre/

5 comments

You're reading it too politically. It says right up in the first paragraph:

> While LLVM is an excellent optimizer, it isn’t specifically designed for the optimization challenges of dynamic languages like JavaScript.

LLVM was, more-or-less, designed around C++ semantics. B3 is not going to be a better C++ compiler than LLVM. LLVM is not going to be a better JS compiler than B3. They're taking different evolutionary paths.

LLVM compiles fast code for things that aren't C++ as well. Maybe you could say it's biased towards static languages.

Also its compilation speed is supposed to be fast in terms of AOT compilation, but not necessarily fast enough for JITing javascript in web-pages.

Not a knock on LLVM. The conditions are just different. There is no software that is 100% great at every single thing - that's why Windows embedded CE failed while iOS and Android thrived on phone and mobile devices.

VxWorks is great at driving martian rovers, but would be horrible at running Adobe Photoshop or Maya.

Why does everything either need to be a snub or a boon?

LLVM is great at generating compiled binaries - it just takes resources (time + memory) to do so - in practical terms, the compilation time only affects the programmers and developers running multiple compiles over a work day, working on the codebase itself. For consumers who are running the programs, LLVM makes great optimized binaries.

In a JS engine, the compiler doesn't have access to the source code until a user loads up the page, so it's in essence doing "compilation" on the spot. And in this case compilation memory and time usage matters.

Swift itself is a "compiled" lanugage - meaning that in development, a developer needs to hit that "compile" button in XCode to generate a binary file which is then distributed and run. In this case, LLVM can use all cores on that big honking Mac Pro or shiny MacBook Pro 15" retina all it wants - take all 16 cpus and 32 gigs of ram and crank it and make a nice binary that comes out optimized to run on a iPad Air.

Of course things like Java conflates the two styles (source code compiled to bytecode and then to run on the JVM) - but in the Java ecosystem there are significant optimizations in both the compile phase (ie javac helloworld.java) as well as ahead of time compilation in the JVM itself.

LLVM is designed for languages that are compiled ahead of time like C and C++. In these cases it's not that important how much time and memory it takes to compile something.

If you're working on a JIT, this matters. A lot. Webkit isn't the first project has has used or worked with LLVM in this manner and abandoned it. PyPy has also investigated using LLVM and stopped doing that.

LLVM isn't bad, it just isn't good at solving this problem it wasn't designed for. If anything, I think it's remarkable LLVM has worked out as well for Webkit as it did.

Swift is generally ahead-of-time compiled, so compile speed doesn't matter as much. Many of the core parts of Swift also avoid highly dynamic semantics. The most dynamic parts are when interfacing with Objective-C classes, an area that has not been heavily optimized yet.
Swift is not a dynamic language. It's statically typed.
On the typing front, maybe you'd find this recent paper entertaining: "Is Gradual Sound Typing Dead?" (link below)

The conclusion is that it's mostly dead or worse, because of the performance hit when typechecked code calls untyped code.

(And also because of the details of Typed Racket, which perfectly reasonably translates into ordinary untyped Racket, but then that is then mangled by GNU lightning (!).)

But...

"At the same time, we are also challenged to explore how our evaluation method can be adapted to the world of micro-level gradual typing, where programmers can equip even the smallest expression with a type annotation and leave the surrounding context untouched. We conjecture that annotating complete functions or classes is an appropriate starting point for such an adaptation experiment."

http://www.ccs.neu.edu/racket/pubs/popl16-tfgnvf.pdf

This comment, and the parent comment, seem to be conflating "dynamic language" with "dynamically-typed language".
What's a "dynamic language"?
Dynamic languages are (generally) not compiled ahead of time. It is possible to have static typing in a dynamic language in the sense that the code is interpreted at runtime (but the types are set statically in the code), and there is no "binary" that one runs.

It used to be called interpreted language or "scripting" language - but I think the vocabulary shifted so the word "dynamic" more encompasses what the languages are about.

By that definition, AFAIK, Swift is neither a dynamic language nor dynamically typed.
According to Apple itself, Swift is a compiled language, and there is no use of the word "dynamic" or "dynamic language" on Apple's website

https://developer.apple.com/swift/

As to whether it is dynamically or statically typed - it's easy to tell - do you need to indicate a variable is an int or a char or a string before you start using it? and do you have to cast the variable to different types when using functions that expect a certain type? If so - it's statically typed. Dynamically typed languages allows you to give an character "5" to a function that expects an integer (ie the number 5) and then automatically converts it so for example the final result to 5+"5" is int(10). Or when you try to print it, it gives you a string literal "1" and "0" without you having to recast it yourself.

Obviously having dynamic typing makes things easier for humans, but the computer has to keep predicting what the programmer is going to do with that variable, so it has some runtime and compile time weaknesses in performance, memory usage, as well as less strictness in compile-time checking - which might allow certain types of errors to sneak by, whereas static typing is very direct - you have to instruct the computer to do every casting from one type to another, etc., and the statically-typed compiler is a sadist - it will fail all your code over and over again until you get all the types right. The difference is extremely noticeable even for a novice programmer.

https://developer.apple.com/library/ios/documentation/Swift/...

says that Swift is "type-safe" (compiler is a sadist and will halt on all type errors) but has type inference so you don't have to explicitly indicate the typing of a variable. I would consider it to be heavily on the statically-typed side though - since it seems the language won't let an integer variable all of a sudden also be a string - you have to cast it properly first.

Not sure where the confusion comes from, probably from people putting buzz words to everything that is new regardless of applicability.

Either way, you are correct, swift is not "dynamically-typed" and neither is it a "dynamic/interpreted" language.