Swift is not
splasmata.com
splasmata.com
(it's not a great test but it's a test)
Given I've found some other articles that claim that it's not that slow but none of them really present any data.
I guess that it depends on your definition of "major factor".
With Swift you can't do that. You have to wrap the calls and generate bridge headers. What a pain.
I'm not an Objective C programmer unless I can avoid it (C++ most days) so I can't really say if he's right or not. (Though, if I had to guess, I'd say he is)
And microbenchmarks (and it doesn't get much more micro than "loop without doing anything") in particular have always been very poor predictors of real performance in my experience. They can be useful when trying to improve a specific area, but they should not be used for bold pronouncements.
I'm not suggesting malicious intent at all here. People make mistakes, and contrary to what seems to be popular opinion, good benchmarks are hard.
[1] https://twitter.com/Catfish_Man/status/473752917347139584
If you have better numbers, please share them!
GP said with optimization he got similar numbers, and without optimization he got significantly worse numbers. It was crystal clear.
> You measure performance and compile without optimization?!
GP clearly stated he compiled both with and without optimization, and characterized (qualitatively) the results of each compared to the results in the article.
Yes. Similar numbers to the ones posted when compiling with optimization. Significantly worse when compiling without optimization.
> You measure performance and compile without optimization?!
No, I tend to measure with optimization. In fact, I personally don't do Debug builds at the all. However, when the numbers were so bad, I did a Debug build to cross check, and lo and behold, those numbers were even worse.
That clear things up?
https://gist.github.com/anonymous/4df3610970891c6afc5a
https://gist.github.com/anonymous/7d7fcf0a5ce24c37999c
ObjC: 0.063209, Swift: 0.255287 (Release)
ObjC: 0.060600 Swift: 5.200207 (Debug)" [2]
[1] https://twitter.com/milend/status/474349620311883776
[2] https://twitter.com/milend/status/474354899527155712Turns out, at least 82.9% of it was just swift_retain / swift_release (ref counting). Whether those retains / released can be optimised away, I don't know, we'll have to wait and see.
Swift -
var j : Int = 0
var k : Int = 0;
var i : Int = 0;
for (i = 0; i < 1000; i += 1) {
k = 0;
for (j = 0; j < 1000000; j += 1) {
k += j % 7;
}
}
C - int j = 0, k = 0;
int i = 0;
for (i = 0; i < 1000; ++i) {
k = 0;
for (j = 0; j < 1000000; ++j) {
k += j % 7;
}
}
update: If I use "fastest unchecked" mode when building swift instead of the "fastest" mode, the swift version is 8% faster than the C version.machine: 1.7GHz core i5 macbook air (mid 2011), 4GB RAM.
edit: For clarity, "1.5x slower" means "swift took 1.5x the time C took" and "8% faster" means "C took 1.08x the time swift took".
edit: To OP - Please put a link to your benchmark source and projects somewhere, or show your project settings as a snapshot or something. For one, I don't believe any of your results based on my own trials.
edit: Changed ++i and ++j to i+=1 and j+=1. This is the version that is 8% faster than C. OP seems right in that i+=1 seems faster than ++i.
edit: (It's becoming impractical to keep this in sync with my project.) When using Int/int, I get swift 8% faster and when using Int64/int64_t, I get C to be 17% faster.
create working and correct program with all the comfort of modern languages / IDEs
-->
switch to unchecked-but-warn (or whatever that's called like), run some test suites and get rid of all warnings.
-->
switch on highest optimizations and switch off checking, verify results.
-->
port to multicore / multinode / accelerators using some directive based approach.
note that you won't have much safety on todays' accelerators anyways, so removing that safety net when still in an easily debuggable environment is going to make life easier when debugging the accelerated code - it's all about being able to exclude error classes.
My guess is only arithmetic checks and not array bounds checks. If array bounds checking is removed, the language won't be any safer (security wise) than C, hence I think that's kept through out.
Btw "Int" and "Int64" in Swift are actually "struct"s and not a primitive type like in C. So the compiler is indeed able to keep performance for these small structs on par with primitives. This is promising for swift's claimed speed I think. These structs have extension methods like uncheckedAdd(), uncheckedDivide() and so on, which lends some evidence to my "unchecked refers only to arithmetic" guess.
edit: .. that Int/Int64 are structs means that the + and += are all overloaded operators, compared to the raw operators used in C. Given that, the compiler, I must say, is impressive.
Here is why I said what I did (and I did mean the former) --
My micro-benchmark is actually comparing the struct-based code in Swift with primitive-based code in C. If "k += j % 7" is to be interpreted literally in Swift sans optimization, it would be two function calls and two stack word copies (structs go on the stack and by copy, whereas classes go on the heap and by reference). k and j are both structs and so operator overloading is needed to write this expression. That the Swift compiler generates comparable-to-C performance in these cases is good news I think.
One major caveat with these benchmarks is that the same LLVM backend is being used for both. I'd like to be able to compare Swift with C/ObjC as compiled by GCC as well for a truer picture of "faster than C".
For practical purposes, I think this is nicely close. I haven't tried the ObjC bridge yet though.
Int/int : Swift = 2.7s, ObjC = 3.4s (Swift is 25% faster)
Int64/int64_t : Swift = ObjC = 2.7s (indistinguishable)
edit: Swift compiler is still building in "fastest unchecked" mode for both.
Without source, disassembly, and something that you can test for yourself, this benchmark is rather uninformative.
In two months, after people start to understand what's going on, where the trouble spots are, and what the right way to fiddle bits, if we are still seeing performance like this, I'll be interested.
Swift seems self-defeating.
1. http://stackoverflow.com/questions/24022172/does-swift-use-m...
I don't have a Mac capable of running any of the dev tools at the moment, but the implications of the section in the manual on the Int* types don't indicate they're boxed at all, nor give any reason why they should have to be.
Of course, if he's declared everything as an NSNumber it could explain some of the results. But obviously, so could them currently being boxed. Either would probably account for the ++ performance problem, especially if it's post-increment, since that probably involves making a copy.
I think the OP is just confusing the fact that they have expandable type as indicating that they have a virtual type.
Consequently, I would propose that there is no excuse for a public release of a commercial programming environment to be so slow unless it introduces significant novelty sufficient to render the preceding work inapplicable.
When Golang first appeared it was quite fast. Swift is not, apparently.
However, I understand that 1.1 and 1.2 has much improved code performance.
How about user facing apps? Haven't we been through this a billion times on language of choice for job. Java, python, php etc. Each has a use. For a lot of what Swift will probably and should be used for I don't see this being an issue that hasn't already been beaten to death.
For most purposes, a user of your software is not going to feel the difference between 0.0006 seconds and 0.06 seconds. One is 100x faster, so is "better", but no user will care.
The stuff that is really expensive (3D graphics, etc.) that users care about are being handed off into custom APIs that are highly optimised and hardware acceleration anyway.
What's more important for most programmers when choosing a language is not "how fast is it for this code to run?", but "how quickly can I ship code?"
Code in the app store next quarter is going to beat code you never get shipped, every single time.
Not long ago I had a project I thought would be perfect for Haskell. I don't know Haskell but I am a very experienced Ruby-ist. I thought about using the project as a means to learn Haskell but wanted the code shipped within a month. I did it in Ruby. It's probably slower, it's perhaps not as elegant as a Haskell solution. But it's shipped. And that therefore beats the Haskell solution which does not exist.
Swift appears to have modern features that mean many programmers will feel more comfortable developing applications using it, many of whom would have struggled with Obj-C.
In that sense, it's going to beat Objective C for performance in the only benchmark that matters commercially: the one that gets ideas into user's hands the quickest.
If you think the rate of development so far has been fast, well, just watch. It's about to get mental.
I don't expect an academic to understand that, nor would I expect most junior/undergrad devs, and I can see in some special cases you would want to think about optimisation (in which case turn that little piece of code into C and link it in), but in the real World, that's how coding works.
Also with the fact that Apple says they will be breaking code as time goes on I'll also be on the Swift sideline for now.
Edit: Why are people finding this comment so offensive ?
Is there something about the semantics swift that you think would inherently permit faster code than well-written ObjC?
Edit: I don't know why this comment was down voted -- it's a perfectly reasonable question that others have responded to. Oddly, the parent comment _I_ was responding too is apparently also being down voted. WTF?
Strong types are far easier to optimize.
Typically a language's efficiency comes from its ability to restrict ambiguity. E.g. a scoped sequence of expressions without gotos allows the compiler to eliminate variables, reorder statements, unroll loops etc because it can see 100% of the uses of a variable by examining that scope. On the other extreme a language like BASIC is harder to optimize in such a fashion because the program counter could be set into the middle of the loop, and because all variables are global, they have to survive the scope.
I am genuinely interested if their are features in swift that aren't also in ObjC.
A language can be equivalent to another and still be easier to program in because the cognitive load on the programmer is lower so good code can be written more quickly. Swift seems to be an interesting attempt at doing that. But that's orthogonal to the question of compiled efficiency.
Totally agree with your 'reduce ambiguity' observation, and I think long term Swift will do very well there. It will also will allow tooling to radically improve from what it is, and multicore to have a reasonable chance to be helpful.
Imo it seems a lot of the language decisions they have made are to make it more compiler/memory friendly (eg the way assign works with arrays). That bodes well for speed/memory/battery I think.
I certainly don't think that Apple was outright lying in their benchmarks. Those sort of shenanigans are a PR nightmare, and nobody thinks its worth it anymore.
I'm curious which period you're referring to here. I haven't been following Apple presentations in detail for a while, but I remember the iPad 2 announcement was chock-full of flat-out lies. Do you mean that this is something that's changed since then (March 2011)? Or do you mean that it's not worth it for developer-focused presentations vs consumers (who would presumably be more credulous)?
EDIT w/ source: http://fortune.com/2011/03/03/steve-jobs-reality-distortion-...
Do you have anything concrete to back this up with?
Here's an article that's pretty succinct about the inaccuracy and lies in the iPad 2 announcement: http://fortune.com/2011/03/03/steve-jobs-reality-distortion-...
All companies tweak the truth to make themselves look good (which company was touting their huge sales numbers when they had barely sold any products to actual customers, just retailers?). Apple aren't alone, they just get the most press.
As you said, this is common practice, and Apple may or may not be one of the more egregious offenders [1], but it doesn't matter. I wasn't saying anything about Apple being shittier than other companies in this regard; I was responding to the parent commenter's claim that a company wouldn't do something like that these days. Now how the fuck is your claim of "Every company does this, leave Apple alone!" not in full support of my point (and arguing against a point that, as near as I can tell, nobody made)?
[1] IMO the lie about the Samsung quote is a level of dishonesty you don't see all that often but my point is that differences in degree like that aren't really relevant
A smug sense of superiority.
I mean, as opposed to users who won't run benchmarks.
As a sidenote, i've recently heard Core Data wasn't used internaly by Apple. Makes me think that i'll skip to swift once apple gives me the list of which of their app is coded with this language.
Also, for many of the tests where it was a 400% or order of magnitude knock in performance there are a lot of comments in here refuting those results, so I'm not sure what to think yet.
From a PL / compiler standpoint it's pretty obvious that Swift is not going to match Objective C from a performance standpoint. That's why Apple used a micro benchmark comparing a static, compiled language vs a dynamic, interpreted language (Python) for marketing purposes.
> We can’t know exactly what’s going on behind the scenes, but my hunch is some of what we take for granted in Objective-C – the straight C scalar data types – are actually classes in Swift. And the more you rely on classes, the more Automatic Reference Counting is in there somewhere, retaining and releasing like there’s no tomorrow, often for no good reason.
If they switched from primitive types to classes for built-in types, that means vtables and an additional memory lookup per element access weakening caching and memory locality.
Creating a Swift int would involve instantiating a class, incrementing the ARC count, and storing data compared to only storing data for primitive types. That explains why appending Swift's Ints to an array is so much slower than NSNumber.
On a side note, this isn't as much of a problem with Java—despite everything being implemented with vtables—because of JIT and better CPU branch prediction.
Disclaimer: I have no Objective C / Swift experience.
> That's why Apple used a micro benchmark comparing a static, compiled language vs a dynamic, interpreted language (Python) for marketing purposes.
This shows a deep misunderstanding of Objective-C and Swift. Swift has way more type information at compile time than Objective-C, and thus gives the compiler much more room to optimize (in addition to being safer). My guess is we'll see Swift eventually be faster than Objective-C at just about everything. For instance, they could unbox class instances into values where possible, which is something they're probably not doing much of yet.
However, if you actually put your mind to it, for the 1-5% of code that actually matter, performance-wise, it is hard to beat the performance, and more importantly: predictability, of C.
It probably makes no difference in the majority of common iOS/OSX development, though.
https://devforums.apple.com/message/974858#974858
The only issue I've ever had is the blatantly obvious one of reallocating std::vector as it grows. You really want to reserve() enough space in advance if at all possible, because copying large chunks of memory is not fast.
To answer your question, in my experience when the standard doesn't mention the desired performance characteristics of a function or method, even the popular STLs (libstdc++ and libc++ certainly) optimize for maintainability over performance. Not sure I can pull up an example of this right now but they are numerous. A good place to start is the standard containers other than deque or vector.
A bigger issue IMO is that the existence of some methods in various standard classes/templates really murder performance, no matter how good the implementation is. One particularly bad example is the bucket() method, local_iterator types, etc. in c++11's unordered_map (probably the rest of the unordered family too). These force the table to be implemented in such a way that every insertion requires a heap allocation, and iteration requires much more pointer chasing than would otherwise be necessary (e.g. with a probed implementation), which is... unfortunate for the cache.
Xcode or command line ?
Testing isolated things like empty loops or ...a single assignment. Those really don't make sense for modern compilers. The dead giveaway is having to modify your code in weird ways, so you don't trigger dead code elimination. If you trigger dead code elimination it means you code isn't producing anything, and you're benchmarking various edge cases that won't occur in the real world.
You need to at least implement a simple algorithm or some small unit of functionality that makes sense in a real program. Swift's compiler is designed to aggressively inline and remove reference counting overhead in cohesive units of code, however if you test everything statement by statement, then whether you enable optimization or not, it can't optimize that much.
That said I don't mind the article. It might help Apple discover places where Swift might be made even faster.