Live data from Hacker News

Swift Resistance Explored

owensd.io

1–10 of 14 posts

Re: Swift Resistance Explored

#4
I am also still exploring Swift, so forgive me if I got this wrong, but isn't the problem here the following:

Your RenderGradient() takes a RenderBuffer struct. Structs are passed by value. So two things happen in your RenderBuffer function:

1) You get a copy of the RenderBuffer, which means it and its contents (a lot of Pixel instances - Arrays are passed by value too!) will be copied every iteration

2) The work you do on the pixels in the RenderBuffer copy has no effect: you change the values of a copy and then ignore the copy. You don't return the modified RenderBuffer it from RenderGradient() or do anything with the result within RenderGradient().

So I think the reason you see such a big difference in this test between optimization and no-optimization is that in the first case, with optimization, the compiler knows that the work you do in RenderBuffer is a waste of time and simply does not do it.

While in the debug build the compiler does not apply optimization so your useless code is still executed.

You can confirm this by looking at the generated code. Or maybe simpler, render the RenderBuffer in an actual buffer or image for a visual inspection.

Re: Swift Resistance Explored

#5
post #4

I am also still exploring Swift, so forgive me if I got this wrong, but isn't the problem here the following: Your RenderGradient() takes a RenderBuffer struct. Structs are passed by value. So two things happen in your RenderBuffer function: 1) You get a copy of the RenderBuffer, which means it and its contents (a lot of Pixel instances - Arrays are passed by value too!) will be copied every iteration 2) The work you…

[deleted]

Re: Swift Resistance Explored

#6
post #4

I am also still exploring Swift, so forgive me if I got this wrong, but isn't the problem here the following: Your RenderGradient() takes a RenderBuffer struct. Structs are passed by value. So two things happen in your RenderBuffer function: 1) You get a copy of the RenderBuffer, which means it and its contents (a lot of Pixel instances - Arrays are passed by value too!) will be copied every iteration 2) The work you…

I think you are correct, and it (as expected) changes the results. I ran owensd code on my machine, in a completely non scientific and error prone setup. For release builds:

Objective-C: 0.0310617s

Safe Swift (incorrect): 0.0641295s (106.5% slower)

Safe Swift (correct): 0.0355441s (14.4% slower)

So the "safe" Swift version is running about 14.4% slower than the Objective-C version. It's not bad at all for a language that is so young! In debug mode, however, I didn't even have the patience to wait for the test run to finish...

Re: Swift Resistance Explored

#7
post #4

I am also still exploring Swift, so forgive me if I got this wrong, but isn't the problem here the following: Your RenderGradient() takes a RenderBuffer struct. Structs are passed by value. So two things happen in your RenderBuffer function: 1) You get a copy of the RenderBuffer, which means it and its contents (a lot of Pixel instances - Arrays are passed by value too!) will be copied every iteration 2) The work you…

Yes, the var should have been inout. It had an affect on the release build performance (twice as fast), but not the debug build. I've updated the blog post.

The performance problem is regarding all retain/releases though; not the copy of the data. That's why the debug builds are not affected.

Re: Swift Resistance Explored

#8
post #7
post #4

I am also still exploring Swift, so forgive me if I got this wrong, but isn't the problem here the following: Your RenderGradient() takes a RenderBuffer struct. Structs are passed by value. So two things happen in your RenderBuffer function: 1) You get a copy of the RenderBuffer, which means it and its contents (a lot of Pixel instances - Arrays are passed by value too!) will be copied every iteration 2) The work you…

Yes, the var should have been inout. It had an affect on the release build performance (twice as fast), but not the debug build. I've updated the blog post. The performance problem is regarding all retain/releases though; not the copy of the data. That's why the debug builds are not affected.

[deleted]

Re: Swift Resistance Explored

#9
One thing that i want to add is that this whole exercise is actually a straw man. You yourself start your post with

"Problem Statement : Design an algorithm that fills in a buffer of pixel data"

If that is the problem, then do that. Do not fill an array with Pixel object references. It is not the same problem.

I am not denying that Swift has performance issues. I do think your test and proof is artificial: nobody would use the 'Swift Safe' method to manipulate pixel data. This is exactly why the unsafe features exists.

I think what you need to discover is how to use structs, classes and raw buffers. None of those is a golden hammer. If you have performance problems with one of those then that does not mean that it is flawed. It is likely simply a bad choice for the problem at hand.

Re: Swift Resistance Explored

#10
I can understand the frustration. However I think it's a little premature to cast aspersions on the whole language because it isn't good at this particular test right now.

We still have ObjC. The two languages work together. (we also have C and asm). Pick the right tool for the job, and have reasonable expectations about the maturity and progress of Swift.

Post reply on HN