7 ms·
How Swift could potentially be faster than Objective-C
- CountHackulus 12y agoSo it's not really the secrets of Swift's speed, it's more like not doing what made Objective-C slow.
- gress 12y agoObjective-C isn't slow. It's a strict superset of C, so anything that C can do fast, Objective-C can do just as fast. If you say Objective-C is slow, you are also saying C is slow. Objective-C provides a message passing mechanism that trades speed for convenience. It turns out that programmers often choose convenience over speed because of time pressure.
- erichocean 12y agoGoing further, writing just C code to replicate what the Objective-C runtime actually does (dynamic dispatch) is also slower than Objective-C and it's hand-tuned, written-in-assembler runtime at those same tasks. So, Objective-C (at least on Apple's operating systems) is as fast as C AND faster than C at a few highly specific things.
- deleted 12y ago[deleted]
- thegeomaster 12y agoThis is basically the speed advantages of C++ applied to Swift, a more powerful language. C++ also uses vtables and compilers often inline calls to methods if the method/type can be determined at compile time. The argument as to why it can be faster than plain C is very weak, though. It says that if C programmers don't use the restrict keyword, equivalent Swift code can be faster. This is right, but ignores the fact that careful and competent C programmers will put restrict in all the places where performance matters. It's very hard to be faster than plain C, because it has a long, long history, and as a result, the compilers have been steadily improving for a long time. It is also less powerful allowing you to be closer to the actual assembly code that is to be generated. But with increasingly better hardware, the speed gains of plain C are diminishing. Yes, you can be very fast, but is it worth the trouble of expressing yourself in such a low-level language? Also, since you can't type-pun (alias) in Swift, you can't do some things that can be done using plain C, so it is unclear how it can be faster.
- PeterGriffin 12y agoIf you read carefully, it's not just the advantages of C++ applied to Swift, because Swift avoids certain weaknesses of C which C++ can't (like said aliased pointers etc.). Swift is much more strict in terms of typing than either C or C++. Pointers are safe, there's no null, etc. It's the strict typing which translates to the compiler knowing more about your program before it runs, and therefore it can do more transformations without changing intent.
- stephencanon 12y ago> Also, since you can't type-pun (alias) in Swift, you can't do some things that can be done using plain C, so it is unclear how it can be faster. Type-punning is never necessary in C; it can always be replaced with one or more calls to memcpy( ), which the compiler can elide (clang, at least, is quite good at this optimization). I don't see any reason why this approach wouldn't work with Swift.
- pcwalton 12y agoLLVM isn't as good at memcpy optimization as you might think. The MemCpyOptimizer pass isn't ordered very well in the pipeline and can't make use of the SSA infrastructure that the rest of LLVM uses. Source: I'm fighting this right now in rustc and plan to fix it by just making the frontend emit fewer memcpys.
- stephencanon 12y agoIt's been a few years since I've seen clang/llvm fail to elide a memcpy used in place of type punning (it's an idiom that I use very frequently as a library writer, and care a lot about). If you have examples of cases where llvm fails to do this optimization, please file a bug report and I will be delighted to lean on the right folks to get it fixed. You shouldn't need to work around it.
- personZ 12y agoand even claimed to be faster than C for certain cases -a promise made for pretty much every language ever. Just need a couple of compiler tune ups. Not trying to be critical, that just gave me a chuckle. On most architectures (including x86-64, ARM, and ARM64), the first few parameters to a function are passed in registers To add to this, the Microsoft 64 calling convention is that the first four integer parameters (which includes pointers), and the first four floating point values, are passed in registers. The System V AMD64 ABI (used by Linux and others) passes the first 6 integer and the first 6 floating point parameters in registers. ARMv8 convention is that the first 8 integer/pointer values, and the first 8 floating point values (so up to 16 values) are passed via registers. This isn't all win, of course -- if your code was using those registers, to hold local variables for instance, it needs to save and restore them, or simply avoid them. In most cases it would be the latter given the abundance of registers. The whole aliasing bit was just weird and detracts from the piece. Anyone who is doing pointer-based-operations in base C is using restrict as appropriate.
- mikeash 12y agoDid you look at the aliasing examples beyond the memcpy reimplementation? It can affect perfectly normal code where you'd never think to use restrict.
- corysama 12y agoExactly. Yes you can use restrict. And, you probably will when writing benchmarks. But, this isn't about speeding up benchmarks. This is about speeding up real world production code with real world production deadlines. Are you really going to intelligently and correctly apply restrict to every function you write where it could help in your next commercial product? Do you really expect everyone on your team to do the same and never screw up? Then there's the teeming masses of app developers who aren't quite as awesome as you. You don't care about them, but Apple does. Apple knows most of them couldn't restrict their way into a box ;) But, they still churned out a billion apps that are used by billions of users. Doing whatever we can to trick them into speeding up their code will literally save untold lifetimes of cumulative lag for the users.
- chton 12y agoThese aren't exactly secrets, are they? Vtables and similar optimizations have been used in Java and .Net compilers for a long time. For a good explanation in C# you can read http://netmatze.wordpress.com/2013/04/06/dynamic-dispatch-in-c/ http://netmatze.wordpress.com/2013/04/06/dynamic-dispatch-in...
- mikeash 12y agoWell no, they're certainly not actual secrets. I used the word for two reasons: first, to convey that which mechanisms are actually used in Swift aren't well known yet, and secondly and much more importantly, to make the title alliterative.
- chton 12y agoAlliteration is always a good reason :) I shouldn't have been so short with you. I've just seen one to many articles where Swift is made to be seen as Apple's godly gift to software development, without any references to similar languages. Not that yours is that ofcourse, it just triggered that frustration a bit :)
- mikeash 12y agoI understand and share your frustration. This article is my attempt to counter the "Swift is super fast because rainbows and unicorns" attitude floating around.
- clayallsopp 12y agoInterestingly, Swift (as of now) can be orders of magnitude slower than C/Objective-C: http://stackoverflow.com/questions/24101718/swift-performance-sorting-arrays http://stackoverflow.com/questions/24101718/swift-performanc... I hope/expect the out-of-box performance will improve over time, but I guess it shouldn't be taken as fact that Swift will always be faster than its predecessor.
- tedchs 12y agoNice reinforcement of "performance tricks" almost always equaling "get the computer to avoid doing extra unneeded work that it used to be programmed to do".
- joliv 12y agoA very relevant article: http://c2.com/cgi/wiki?AsFastAsCee http://c2.com/cgi/wiki?AsFastAsCee
- moomin 12y agoTo be honest, right now Haskell's looking like a higher performance language than Swift.
- xooyoozoo 12y agoBecause of actual semantic analysis or some microbenchmark you saw somewhere running on a beta, unstable compiler?
- mpweiher 12y agoVery potentially. The things that can be "faster" are typically not the bottlenecks in Objective-C programs, as the fine article rightly mentions in passing. On the other hand, a lot of the really slow parts of recent Objective-C "enhancements" are now mandatory in Swift, for example the Automatic Reference Counting (ARC) support, which is actually a big part of the 100x and more slowdowns. Another issue is that you have copying semantics by default. The claim is that this can make things faster, but for common objects like arrays and dictionaries it first makes things a lot slower (once they fix the completely borked array semantics). In all of these cases, you have very slow defaults that you must trust the compiler to make fast again. The claim is that the semantics make it easier for the compiler to optimize. This is true, but so far practical experience appears to be that these two don't balance, that is the compilers don't get enough extra information for optimization to compensate for the loss in performance you get from the semantics being expensive by default. Except in well-chosen benchmarks. In fact, even in FP languages that have much tighter semantics and therefore much better opportunities for the "sufficiently smart" compiler to do its magic, you tend to see people dropping down to nasty imperative code (effectively C in all but name) to get decent performance. Swift's semantics are less tight, so I think it's going to depend even more on the programmer writing fast, imperative code, "C in all but name". Again, there are a few things that help the compiler here, but again I doubt they will generally be able to compensate. I think the biggest issue with Swift performance is that it is focused on helping the compiler, rather than the programmer. The performance model is, at least so far, highly non-linear and non-intuitive. This will hopefully get better, but the semantics I've touched on make it difficult, they are inherently highly non-linear and inherently difficult to predict.
- josephlord 12y ago> Another issue is that you have copying semantics by default. The claim is that this can make things faster, but for common objects like arrays and dictionaries it first makes things a lot slower (once they fix the completely borked array semantics). But when they say "copy semantics" (actually I think it was "value semantics") they mean copy on write semantics. There are tricks that they can do to ensure the copy is pretty rare. If the array passed to a function is not used later in the calling function no copy should be needed. If it is not changed in caller or callee then no copy is needed. Yes there may be a hit at times but it should be fairly rare. I'm very glad that they are fixing the borked array semantics, I complained pretty bitterly about that.