[0] https://gist.github.com/lattner/b016e1cf86c43732c8d82f90e5ae...
How many times don't we see bugs, errors or security issues stemming from the fact that business logic gets implemented in C?
Also, what about Objective-C prevents business logic bugs?
Sorry, never tried that.
> Also, what about Objective-C prevents business logic bugs?
Generically speaking C makes it easy to interact with the computer memory but harder to abstract things while OO languages have it reverse.
C has GOTO, Objective-C not.
Objective-C has objects that easily can encapsulate different aspects of your logic. Objective-C is very verbose and readable while most C API's aren't.
Obviously Swift is even better in that regard as it has better types and checks but it doesn't allow you to seamlessly use C.
Not sure if there is a mirror, a write-up, or another example anyone might be able to pass along.
edit: this google cache version is working[0].
[0] https://webcache.googleusercontent.com/search?q=cache:gXiqzW...
Basically, Swift dynamism is coming, hopefully safer than ObjC
> 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.
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.
This is a common misconception. It is not true. Swift is slower than Objective-C, typically significantly so.
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.
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 -- 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.
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...
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?
Hmm...with Objective-C, I get exactly what an optimizing C compiler "would" generate, because that's an optimizing C compiler generating it.
I had not heard the term "runtime-oriented language" before. Is this really just another term for "supports reflection"? If not what would be other examples of "runtime-oriented" languages?
With the possibility to intercept/replace code at runtime (at any time, not just at a resolve/jit stage) it must be very hard for the runtime to optimize calls (i.e make direct calls instead of indirect via method pointer lookup)?
I’m not familiar with how this works in any runtime (V8, Hotspot, ...) so I’m curious which runtimes actually pay one extra method pointer lookup forever and which don’t. I’m guessing the answer for nearly all of them is “it depends”.
Objective-C: Takes one method pointer indirection / jmp trampoline forever, but caches "selectors" on the class so that they become a simple lookup rather than a full evaluation. See sibling comments for better write-ups than I could find.
Most JS runtimes: Trace JITs mean many method invocations are compiled into traces and become either inline instructions or native function calls. Also uses "hidden classes" to implement inline method caching, where the callsite is replaced with the specific address of the call once the dispatch is resolved. https://github.com/sq/JSIL/wiki/Optimizing-dynamic-JavaScrip... , https://blog.ghaiklor.com/optimizations-tricks-in-v8-d284b6c...
Ruby: Also uses inline method caching - when a method is resolved that callsite is replaced with a jump straight to the resolved method in the bytecode. Invalidation used to occur any time a class was modified in any way but has been made more specific over time: https://github.com/charliesome/charlie.bz/blob/master/posts/...
How exactly it finds that method is an implementation detail, but fast implementations will cache the results of method lookups. For example, https://developer.apple.com/library/content/documentation/Co... states:
”To speed the messaging process, the runtime system caches the selectors and addresses of methods as they are used. There’s a separate cache for each class, and it can contain selectors for inherited methods as well as for methods defined in the class. Before searching the dispatch tables, the messaging routine first checks the cache of the receiving object’s class (on the theory that a method that was used once may likely be used again). If the method selector is in the cache, messaging is only slightly slower than a function call. Once a program has been running long enough to “warm up” its caches, almost all the messages it sends find a cached method. Caches grow dynamically to accommodate new messages as the program runs.”
"Dissecting objc_msgSend on ARM64" https://www.mikeash.com/pyblog/friday-qa-2017-06-30-dissecti...
"Let's Build objc_msgSend" https://www.mikeash.com/pyblog/friday-qa-2012-11-16-lets-bui...
There's also the "Illustrated history of objc_msgSend", although it appears a bit dated, it has some nice commentary on the evolution of this very performance-critical part of the objective-c runtime: http://sealiesoftware.com/msg/index.html