4 ms·
> Before we start, Objective-C is a runtime-oriented language, which means that all of the links between your methods and variables and classes are deferred to
by skue 9y ago
> Before we start, Objective-C is a runtime-oriented language, which means that all of the links between your methods and variables and classes are deferred to the last moment possible to when your app is actually running, and this gives you great flexibility because you can change those links. The alternative, where Swift is most of the time, is compiletime-oriented languages. So in Swift everything is a bit more harder bound, and you get more safety, but it’s less flexible.
> This is what this debate was all about.
Not just safety, but also performance. Swift offers significant performance gains when you don’t need the dynamism. Swift lets you opt into dynamic features (as he later explains), and you can seemlessly interact with Objective C on Mac platforms. But you don’t have to pay the penalty for dynamism in the vast majority of your code that doesn’t use these features.
Edited: I also pointed out some additional mistakes in the post, but removed that because this comment got too long.
- mpweiher 9y ago> Not just safety, but also performance. Swift offers significant performance gains This is a common misconception. It is not true. Swift is slower than Objective-C, typically significantly so.
- skue 9y agoWhen arguing against a “common misconception,” one typically provides a source. You seem to be saying that Apple’s claims are not only wrong, but ObjC is somehow faster despite having to do more work. Swift has no runtime method table lookups, no extra objc_msgSend calls, better ability to analyze and inline code, no retain/release dance for code with value semantics, etc. Every benchmark I’ve seen shows Swift faster for these reasons.
- panic 9y agoDo you have experience writing Swift or Obj-C programs? My experience is that Obj-C has predictable performance which is often "good enough", whereas Swift is either too slow (without optimizations) or takes a very long time to compile (with optimizations enabled). As a concrete example, I took a Swift program I had lying around (8 files, 2854 lines total), compiled it without optimizations, and stress-tested it a bit. Here's what the "bottom-up" profile looks like: https://i.imgur.com/ohlKQgx.png https://i.imgur.com/ohlKQgx.png -- tons of time wasted in Swift runtime overhead. Compiling with optimizations removes most of the overhead, but a clean build of this (relatively small) program took almost 5 minutes with optimizations enabled.
- i2om3r 9y agoDid you compare it to a roughly equivalent Objective-C program? The top four entries in your profile data show retain, release and objc_msgSend. You will have those in Objective-C too. Maybe to a different degree? That's also why I am asking whether you have similar Objective-C code to test. Or maybe it's just that unoptimized Swift code is slower and optimized code is faster? Compile times are a related but different matter. There are -warn-long-function-bodies and recently -warn-long-expression-type-checking which are really helpful and can give you an idea where most of the compile time is spent. In my experience, the type checker can spend a lot of time in mildly complex expressions involving overload resolution, which can be really annoying but there are often ways around it. With those culprits being eliminated, I have never encountered 5 minute build times for projects of this size or bigger, and I like to imagine that I write fairly generic code.
- panic 9y agoThanks, I didn't know about those flags! I suspect there was a pathological expression somewhere, since most of that time was spent in a single file.
- gurkendoktor 9y agoIt should be easy to construct Swift code that is much than its ObjC equivalent by failing to account for copy-on-write: https://medium.com/folded-plane/swift-array-appending-and-avoiding-o-n-6082619cdf7b https://medium.com/folded-plane/swift-array-appending-and-av... So Swift is faster than ObjC by a constant factor, until you run into this subtle issue (which didn't really exist in ObjC), and then it's suddenly slower by a full O(n). Whether that's a good trade-off depends on how good of a language lawyer you are. It's C vs C++ all over again...
- mpweiher 9y agoThere are many cases like that. How was that with protocol generics and collections? When can it remove ARC calls? > It's C vs C++ all over again... From a performance POV, it seems to be a lot worse than C++. Much less baseline performance, less predictability, and almost no way to get to peak performance.
- mpweiher 9y ago> 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 https://www.youtube.com/watch?v=Ntj8ab-5cvE Slides: http://llvm.org/devmtg/2015-10/slides/GroffLattner-SILHighLevelIR.pdf 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 9y agoI can't speak for other people's code, but I regularly profile and read the machine code generated by the Swift compiler, at least for my hot loops. If you know what you are doing (use the right annotations and optimizer flags), even fairly generic code often compiles down to something that comes very close to what an optimizing C compiler would generate. Sometimes it generates even faster code, because the Swift calling convention can make better use of available registers. Sure, there are situations where it generates less optimal code, but generally generic idiomatic Swift is on a different level than a (non-profiling) compiler for idiomatic Objective-C can ever come close to. That's my experience.
- mpweiher 9y ago> very close to what an optimizing C compiler would generate. Hmm...with Objective-C, I get exactly what an optimizing C compiler "would" generate, because that's an optimizing C compiler generating it.
- woolvalley 9y agoTooling and maturity are reasons why not currently, maybe give it a couple of years ;) Debuggers can not work properly, xcode indexing can beachball, compile times are quite a bit longer, there is API churn from version to version, a lack of ABI stability forcing you to bundle swift with your app increasing binary size and other bugs.