HN Theater @HNTheaterMonth

The best talks and videos of Hacker News.

Hacker News Comments on
2015 LLVM Developers’ Meeting: Joseph Groff & Chris Lattner “Swift's High-Level IR: A Case Study..."

LLVM · Youtube · 6 HN points · 2 HN comments
HN Theater has aggregated all Hacker News stories and comments that mention LLVM's video "2015 LLVM Developers’ Meeting: Joseph Groff & Chris Lattner “Swift's High-Level IR: A Case Study..."".
Youtube Summary
http://www.LLVM.org/devmtg/2015-10/

Swift's High-Level IR: A Case Study of Complementing LLVM IR with Language-Specific Optimization - Joseph Groff & Chris Lattner, Apple

Slides: http://llvm.org/devmtg/2015-10/slides/GroffLattner-SILHighLevelIR.pdf


The Swift programming language is built on LLVM and uses LLVM IR and the LLVM backend for code generation, but it also contains a new high-level IR called SIL to model the semantics of the language (and perform optimizations) at a higher level. In this talk, we discuss the motivations and applications of SIL, including high-level semantic analyses and transformations such as flow-dependent diagnostics, devirtualization, specialization, reference counting optimization, and TBAA, and we compare SIL's design with that of LLVM IR.

Videos Filmed & Edited by Bash Films: http://www.BashFilms.com
HN Theater Rankings

Hacker News Stories and Comments

All the comments and stories posted to Hacker News that reference this video.
> are not only wrong

Yes, Apple's claims are wrong, sometimes comically so, particularly when it comes to performance. Remember when they claimed that GC was many times faster than retain/release? Also wrong. Or their claim that you should use property lists only for smaller data sets, and keyed archiving for larger data sets? Completely wrong, as keyed archiving uses property lists in its implementation, and always generates larger plists than if directly expressed. So a keyed archive is always worse, performance-wise, than an equivalent plist. And so on and so forth.

Anyway, I have a whole chapter in my book on this, and the numbers tell the story. I obviously can't reproduce the whole thing here.

> but ObjC is somehow faster despite having to do more work.

Another misconception. Swift does a lot more work. It then tries to remove that work through optimization efforts, which may or may not succeed.

A tiny, somewhat extreme example: Swift allocates local variables on the heap. Not as a frame, but individually. At least initially. Now of course this would make code many orders of magnitude slower, so the optimizer (this is a mandatory pass, run even at -O0) has to remove this if it can. However, this is just an optimization, so as far as I can tell there is no diagnostics if it fails.

See https://www.youtube.com/watch?v=Ntj8ab-5cvE

Slides: http://llvm.org/devmtg/2015-10/slides/GroffLattner-SILHighLe...

Then there is mandatory/invisible ARC, which can and will get you in an inner loop, without visibility, and with not much recourse. Even Chris has admitted that this is a problem they need to fix. And of course generics are implemented via witness tables, so indirect dispatch at roughly similar costs to objc_msgSend(). The compiler may be able to eliminate this. Or not.

And so on and so forth. I just saw something about blocks always causing heap allocations (and this is corroborated by an attempt someone made to port some HTTP parsing code from C to Swift. Even with max. optimizations and inline craziness, it was ~3x slower).

Or JSON "parsing". The Swift solutions that tend to sit on top of NSJSONSerialization have tended to be an order of magnitude slower than NSJSONSerialization by itself. Which is odd when you consider that NSJSONSerialization uses all the slowest aspects of Objective-C/Foundation: keyed access, heap allocated objects for things that would otherwise be primitives, dictionaries instead of objects (typically 10x slower) etc. Yet Swift on top is 10x slower. The BigNerdRanch's "Freddy" JSON parser tries to rectify those problems by being 100% Swift, without NSJSONSerialization underneath. The result is that it's "only" 4-5x slower than NSJSONSerialization. And again, NSJSONSerialization isn't particularly efficient.

I haven't tested the Swift 4 serialization stuff yet, but both from reports I've heard and cursory looks at the implementation, it doesn't look like a speed demon.

> Every benchmark I’ve seen shows Swift faster for these reasons.

What benchmarks are you looking at?? While it wouldn't be true that I've never seen a Swift advantage, it's pretty close to never.

Now there are a lot of unsubstantiated claims that Swift is fast, because "reasons", but benchmarks?

i2om3r
I can't say anything about JSON serialization performance as I don't have experience with it. Your other points, though, seem a little handwavy to me. Or maybe I am reading them wrong.

> A tiny, somewhat extreme example: Swift allocates local variables on the heap. (...)

Have you ever encountered a local variable that spuriously didn't get stack promoted? I haven't. As I said elsewhere, I regularly read the generated code for my hot loops. Also, when profiling with Instruments, I have never been surprised by a heap allocated local variable that didn't escape. I also don't see why stack promotion theoretically would be a less precise analysis then doing it the other way around. I imagine that if the optimizer misses to promote a local variable, it would be a bug in the same way it would be a bug if an escaping local variable spuriously didn't get boxed (for compilers working the other way). Just that it won't fail at runtime, which might increase the potential for undiscovered bugs. But again, have you ever been bitten by this?

> And of course generics are implemented via witness tables, so indirect dispatch at roughly similar costs to objc_msgSend()

Generic types are opportunistically specialized and in my experience, the optimizer has gotten a bit better in that regard. I find that a nice compromise between C++ and, say, Java. You can also influence the optimizer's decision with various not-yet-stable annotations (@specialized, for example). Sure, if you want to write reliably fast generic code in Swift, you need to know a few things. None of the above is possible in Objective-C, though, because of its type system.

> I just saw something about blocks always causing heap allocations (and this is corroborated by an attempt someone made to port some HTTP parsing code from C to Swift. Even with max. optimizations and inline craziness, it was ~3x slower).

If by blocks, you mean closures, then yes, they are heap allocated if they escape. For non-escaping closures, there is always a way to force an inline unless you pass them to compiled third-party code. Cross-module optimization is an area that is still being worked on. Without knowing anything about the code in the benchmark, from your description, it sounds to me that there is unused potential for optimizations, either by making the code more idiomatic and/or by using one or two annotations. Which brings me to my last point.

> What benchmarks are you looking at?? While it wouldn't be true that I've never seen a Swift advantage, it's pretty close to never.

Do you have links? Not that I looked too thoroughly, but I have never encountered a benchmark comparing Swift with Objective-C (or other languages?) that both (1) showed significant worse performance for Swift across the board and (2) that I trust. Most recent code I have seen that does not perform well could fairly easily be improved or would have to be rewritten in more idiomatic Swift. I specifically say most, since there certainly is still room for improvement, but in my experience it is nowhere as bad as your comment suggests.

mpweiher
> Generic types are opportunistically specialized and in my experience, the optimizer has gotten a bit better in that regard

That's always the answer: "the compiler has gotten better and will get better still". Your claim was that Objective-C has all this "extra work" and indirection, but Swift actually has more places where this applies, and pretends it does not. With Objective-C, what you see is what you get, the performance model is transparent and hackable. With Swift, the performance model is almost completely opaque and not really hackable.

>None of the above is possible in Objective-C, though, because of its type system.

What does the "type system" have to do with any of this? It is trivial to create, for example, extremely fast collections of primitive types with value semantics and without all this machinery. A little extra effort, but better and predictable performance. If you want it more generically, even NeXTSTep 2.x had NXStorage, which allowed you to create contiguous collections of arbitrary structs.

Oh...people seem to forget the Objective-C has structs. And unlike Swift structs they are predictable. Oh, and if you really want to get fancy you can implement poor-man's generics by creating a header with a "type variable" and including that in your .m file with the "type variable" #defined. Not sure I recommend it, but it is possible.

The fact the Foundation removed these helpful kinds of classes like NXStorage and wanted to pretend Objective-C is a pure OOPL is a faulty decision by the library creators, not a limitation of Objective-C. And that Foundation was gutted by CoreFoundation, making everything even slower still was also a purely political project.

In general, you seem to be using "Objective-C" in this pure OOPL sense of "Objective-C without the C" (which is kind of weird because that is what Swift is supposed to be, according to the propaganda). Objective-C is a hybrid language consisting of C and a messaging layer on top. You write your components in C and connect them up using dynamic messaging. And even that layer is fairly trivial to optimize with IMP-caching, object-caching and retain/release elision.

Chapter 9 goes into a lot of details on Swifft: https://www.amazon.com/gp/product/0321842847/

A few Swift issues surprised me, to be honest. For example native Swift dictionaries with primitive types (should be a slam dunk with value types and generics) are significantly slower than NSDictionary from Objective-C, which isn't exactly a high performance dictionary implementation. About 1.8x with optimizations, 3.5x without.

This is another point. The gap between Swift and Objective-C widens a lot with unoptimized code. Sometimes comically so, 10x isn't unusual and I've seen 100x and 1000x. This of course means that optimized Swift code is a dance on the volcano. Since optimizations aren't guaranteed and there are no diagnostics, your code can turn into a lead balloon at any time.

And of course debug builds in Xcode are compiled with optimization off. That means for some code either (a) the unoptimized build will be unusable or (b) all those optimizations actually don't matter. See "The Death of Optimizing Compilers" by D.J. Bernstein.

Anyway, you asked for some links (without providing any yourself):

https://github.com/helje5/http-c-vs-swift

https://github.com/bignerdranch/Freddy/wiki/JSONParser

"Several seconds to parse 1.5MB JSON files"

https://github.com/owensd/swift-perf

But really, all you need to do is run some real-world code.

You also mention looking at the assembly output of the Swift compiler to tune your program. This alone should be an indication that either (a) you work on the Swift compiler team or (b) you are having to expend a lot more effort on getting your Swift code to perform than you should. Or both.

Nov 16, 2015 · 1 points, 0 comments · submitted by jmah
Nov 13, 2015 · 2 points, 0 comments · submitted by tambourine_man
Nov 11, 2015 · 2 points, 0 comments · submitted by gre
Nov 10, 2015 · 1 points, 0 comments · submitted by cloudmike
HN Theater is an independent project and is not operated by Y Combinator or any of the video hosting platforms linked to on this site.
~ yaj@
;laksdfhjdhksalkfj more things
yahnd.com ~ Privacy Policy ~
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.