News for hackers. Stuff that matters.
Re:RubyMotion - Ruby for iOS by sassafras on Thursday May 03, 2012 @08:46PM (#3926491)
I can't speak for the parent, but my take on it is that Ruby is considerably slower than Objective-C and one of the slower scripting languages in common use, IIRC. I wouldn't go out on a limb and suggest that it's unsuitable for iOS development without having a chance to see it myself, but it's something to keep in mind.

As I'm sure you've seen, even Objective-C is too slow for many things when developing for iOS - for instance, if you want to get halfway decent UITableView performance it's best to write a custom UIView where instead of laying out nested subviews, you drop into C and do all your layout in drawRect using only CoreGraphics API calls.

If you're attempting to do anything more complicated than hooking together pre-fab components, your performance is probably going to suck if your views are written in Ruby. And it's the silky smooth graphics people have come to expect that give iOS the reputation it's earned for slick UI.

It doesn't mean you shouldn't necessarily use a framework like this, but you don't get all that convenience for free. I've often felt that the reason Objective-C remains in use (aside from the fact that it's kept alive by Apple) is that it sits in a really practical middle ground between the bare metal performance of C and the convenience (and tradeoffs) of "nicer" languages. As I said above, though, this is just my default reaction, and I'd love to see this stuff in action if it's truly usable for a reasonable subset of use cases.

Re:RubyMotion - Ruby for iOS by Me1000 on Thursday May 03, 2012 @09:16PM (#3926572)
I can only assume you didn't read up on the technology at all. RubyMotion does not use a Ruby VM, instead it's a static compilation to machine code. So any previous Ruby performance benchmarks are invalid in this instance.

Also, Objective-C is not the slow bit in the example you described. There is a lot of logic overhead in laying out views in Cocoa. While it's true Objective-C (the language) may have some overhead, it's not much. And it's certainly not anything compared to laying out a complex view tree.

Re:RubyMotion - Ruby for iOS by sassafras on Thursday May 03, 2012 @11:58PM (#3926940)
It's true, I didn't read up on the tech at all. That was just my initial reaction. If it's fast, great! I'd love to see some performance benchmarks.

As for Objective-C, whether the language in and of itself is the source of the slowness I was talking about is somewhat beside the point, IMHO. I'm aware that laying out views in Cocoa involves a lot of overhead, and that it's as much to do with the complexity of what's going on under the hood as anything. The fact of the matter remains though that you take a performance hit when laying out non-trivial views that need to be updated as fast as possible (e.g. when a table view scrolls by even one pixel and all the views have to be redrawn). You could probably convince me that Objective-C isn't the reason this is the case, but in any event, when you find the need to drop down into direct drawing API calls in order to get the performance you need, the "not much" overhead you're talking about can become much more noticeable. In a tight loop, a factor of 2 can make a huge difference, even though "2x slower than C" would be an enviable benchmark for many languages.

Again, I'm certainly not denigrating Ruby or other languages, but to me, that aspect of iOS development is a reminder that one needs to choose tools carefully for the job at hand. Hence my hesitation at the announcement of alternative toolkits for iOS apps, the vast majority of which I have yet to see any stellar examples of. Here's hoping this will break the mold.

Re:RubyMotion - Ruby for iOS by Zev on Friday May 04, 2012 @04:00AM (#3927514)
The fact of the matter remains though that you take a performance hit when laying out non-trivial views that need to be updated as fast as possible (e.g. when a table view scrolls by even one pixel and all the views have to be redrawn).

Not true, on a bunch of different levels.

A. Go do a benchmark with a nib loaded with UINib, and then with your "non-trivial view". The difference is negligible. You won't get more than 1-2 fps more by keeping it in code. And honestly? If you're that desperate for 1-2 fps, you're not likely bottlenecked at drawing code.

B. If you scroll by one pixel, at most, you'll have one new cell to redraw: the one that appeared on screen at the end. You don't redraw everything all the time.

C. I find that custom code is usually slower than loading some images and placing them on screen. CoreGraphics functions, for example, don't use the GPU. Set the wrong property on your layer (try touching CALayer's shadow properties on a large scrollview)? You lose ~20FPS. GPU is too busy calculating stuff to actually put stuff on screen, so CA drops frame.

Re:RubyMotion - Ruby for iOS by sassafras on Friday May 04, 2012 @01:28PM (#3929417)
Hey, thanks for the comments. I like talking about this stuff.

A. I wasn't talking about loading a nib vs programmatically wiring up a view. Many people never touch interface builder and write all their views from scratch, but in that case you still have the choice between compositing your view using subviews and overriding drawRect with drawing calls. Have you ever has the pleasure setting up a tableview controller on an older (first or second generation) iOS device? The difference in responsiveness there can be quite striking. This may be a topic rendered somewhat moot with newer hardware.

B. That's not my understanding, but if you have a source on that I'd appreciate a link. I was under the impression that while the cell will only be requested once it comes into view, scrolling the table still requires the visible to cells to be re-layed out, which is where the relative inefficiency of subview rendering starts to hurt you. I certainly could be wrong about that though.

C. If I recall, CoreGraphics is implemented on top of OpenGL. You still don't want to do complex graphics in your cell's drawRect in this sort of situation (I'm just imagining an image and a few labels, nothing fancy). Drawing a static image, pre-generated or cached, is a nice solution in some cases.

Re:RubyMotion - Ruby for iOS by Zev on Friday May 04, 2012 @02:33PM (#3929697)
Many people never touch interface builder and write all their views from scratch, but in that case you still have the choice between compositing your view using subviews and overriding drawRect with drawing calls.

Many people overestimate how expensive a view is to lay out, and jump straight into code (I'm as guilty of this as anyone else), without actually stopping to see how nibs perform, due to misunderstanding some part of the pipeline.

Have you ever has the pleasure setting up a tableview controller on an older (first or second generation) iOS device? The difference in responsiveness there can be quite striking. This may be a topic rendered somewhat moot with newer hardware.

Yup. Fun times. Glad we're not there anymore. And given AT&T gives away 3GS's for free, I'd have to agree that the topic's moot and go on to say that it isn't worth the time or effort to support a device that no one has anymore ;)

..but if you have a source on that I'd appreciate a link

Add a log to -layoutSubviews of your cell subclass, and look at how often it gets printed out when you scroll.

If I recall, CoreGraphics is implemented on top of OpenGL. You still don't want to do complex graphics in your cell's drawRect in this sort of situation (I'm just imagining an image and a few labels, nothing fancy). Drawing a static image, pre-generated or cached, is a nice solution in some cases.

Go far enough back, and everything UI-related is OpenGL. CoreGraphics, however, is not built directly on top of OpenGL. It's part of Quartz, (specifically, QuartzGL). QGL on Mac can use either CPU-backed or GPU-backed drawing. On Mac, QGL defaults to CPU-backed drawing, but an app can use the GPU backing instead, by setting QuartzGLEnable to true in Info.plist. This option isn't available on iOS. You're stuck with CPU, only, for CG.