Saturday, December 22, 2012

Android NDK now includes clang with Objective-C support

Apparently, the Android NDK started including clang in ndk-r8c. The Google folk had always disabled Objective-C from their gcc ports, making Objective-C support that much more difficult to achieve, but I had a hunch that disabling Objective-C from clang may well have been more effort than it's worth.

I just tried it with a vanilla, freshly downloaded ndk-r8d and a small Objective-C program compiled without problems, so it looks like my hunch was correct.

Of course, it didn't link because there is no runtime, but providing one is a much smaller effort than reconfiguring the entire toolchain. After that, it gets interesting...

Update: after getting a runtime, it linked and ran on my Galaxy II test phone.

Wednesday, November 7, 2012

Cocoa / Objective-C performance course at Kloster Eberbach

Stefanie Seitz is organizing a Cocoa / Objective-C performance course at Kloster Eberbach, held by yours truly, December 9-12th.

I am sure it'll be fun and hope it will be instructive. If you're interested, give Stefanie a shout!

Update: December was a bit optimistic for all involved, so we're tentatively moving this out to the beginning of March. I'll post the exact date once it has settled.

Thursday, November 1, 2012

CGLayer performance and quality

The CoreGraphics CGLayer object seems to keep causing confusion. I hope I can clear that up a bit.

The intent of CGLayer was to have some sort of object for optimized repeated drawing, similar to how you would call a drawing procedure multiple times, have multiple instances of a view or simply draw the same PDF or bitmap image multiple times. The difference was supposed to be that the drawing layer could do secret magic "stuff" to optimize the repeated instance drawings. Not giving away the specific representation or optimizations performed means that whatever is done can be adapted both to different contexts and with changing technology.

Currently, that primarily means a texture stored on the graphics card, and that is and was one of the possible optimizations. However, the reasoning for such an opaque optimized object goes back further, at least to NeXTStep/Rhapsody: DisplayPostscript was implemented as a server process, and despite Mach's fast memory-remapping messages, shipping images back and forth between the client and server was not an optimization, and so you couldn't use (client side) bitmaps for optimized drawing. Well you could, but it wouldn't be optimized.

With Quartz becoming a client-side drawing library in Mac OS X, some of the reasons for these distinctions disappeared, but the distinctions (such as NSBitmapImageRep vs. NSCachedImageRep) remained. I think there were plans for CGLayer to become a kind of NSCachedImageRep on steroids, for example maintaining OpenGL display lists, but as far as I could tell, those plans never really panned out: in my tests drawing a CGLayer always looked the same as drawing a cached bitmap, and also performed similarly.

In 10.5, most of the accumulated cruft was cleaned up, NSBitmapImageRep for examples is now only a fairly thin wrapper around its underlying CGImage, and NSCachedImageRep was deprecated completely in 10.6, as it no longer has any advantages. With these changes, drawing a CGImage or a NSBitmapImageRep became as fast as possible, with CGImages stored on the graphics card. At this point CGLayer was essentially abandoned, and for drawing to the screen, you can just as easily use a NSBitmapImageRep, CGImage, UIImage etc.

So is CGLayer now completely useless? Not quite! It turns out that when drawing to a PDF context, CGLayer will generate a PDF Form object, which stores the original drawing commands (vectors, text, images). This is obviously much better than drawing a bitmap, both in terms of quality and in terms of file size and performance.

So if your plans include printing or generating a PDF, then I would recommend taking a look at CGLayer for repeated drawing of (vector) content.

Thursday, October 18, 2012

Little Message Dispatch, aka "Sending Primitives to the Main Thread"

Just ran across a Stack Overflow question on using primitives with performSelectorOnMainThread:. The original poster asks how he can send the message [myButton setEnabled:YES] from a background thread so it will execute on the main thread.

Alas, the obvious [myButton performSelectorOnMainThread:@selector(setEnabled:) withObject:(BOOL)YES waitUntilDone:YES]; is not only ugly, but also doesn't work. It used to kinda sorta work for scalar integer/pointer parameters that fit in a register, but it certainly wasn't a good idea and started breaking when Apple started to retain those parameters. Casting a BOOL to a pointer and back might work at times, sending it a retain will definitely not.

What to do? Well, I would suggest the following:



[[myButton onMainThread] setEnabled:YES];


Not only does it handle the primitives without a sweat, it is also succinct and readable. It is obviously implemented using Higher Order Messaging (now with Wikipedia page), and I actually have a number of these HOMs in MPWFoundation that cover the common use-cases:

@interface NSObject(asyncMessaging)

-async;
-asyncPrio;
-asyncBackground;
-asyncOnMainThread;
-onMainThread;
-asyncOn:(dispatch_queue_t)queue;
-asyncOnOperationQueue:(NSOperationQueue*)aQueue;
-afterDelay:(NSTimeInterval)delay;


@end

There is a little HOM_METHOD() Macro that generates both the trampoline method and the worker method, so the following code defines the -(void)onMainThread method that then uses performSelectorOnMainThread to send the NSInvocation to the main thread:
HOM_METHOD(onMainThread)
        [invocation performSelectorOnMainThread:@selector(invokeWithTarget:) withObject:self waitUntilDone:YES];
}

You can use MPWFoundation as is or take the above code and combine it with Simple HOM.

Monday, October 15, 2012

CoreGraphics, patterns and resolution independence (not just) for retina displays

In a recent post with followup, Mark Granoff demonstrates how to intelligently deal with the need for higher resolution backgrounds by using CoreGraphics pattern images, particularly using the [UIColor colorWithPatternImage:] method. However, he does wonder why he still has to deal with retina resolution issues at some points in the code, when "…the docs say that CoreGraphics handles scaling issues automatically."

That's a good question, and the answer lies in the fact that the example uses pattern images and mask images, rather than CoreGraphics patterns and geometric primitives. Once you explicitly ask for bitmap representations, you will be dealing with pixels and different resolution. The clue is to avoid going to pixels as much and as long as possible. The doughnut shape, for example, can easily be achieved using basic geometry and a little knowledge of the Postscript/PDF fill rules.

Using the standard "nonzero-winding-number" rule, a doughnut effect can be achieved by having the two arcs that are nested inside each other drawn in opposite directions. That's one of the reasons the extra "clockwise" parameter exists.


  NSPoint centerPoint = NSMakePoint([view frame].size.width/2, 150);
  [context arcWithCenter:centerPoint
           radius:50 
           startDegrees:0
           endDegrees:360  
           clockwise:YES];
  [context arcWithCenter:centerPoint
           radius:100
           startDegrees:0
           endDegrees:360  
           clockwise:NO];
  [context fill];

(The code examples here use MPWDrawingContext for convenience, pure CoreGraphics code tends to be two to three times more verbose). The second way to achieve the doughnut would be to just use the even/odd fill rule, in which case the direction doesn't matter. matter.

Patterns can also be specified geometrically, or rather with callbacks to draw the pattern shape. Objective-C Blocks are really a perfect fit for specifying these sorts of callbacks, but were only introduced much later than the CoreGraphics pattern callback API. The following code shows how to specify the diamond pattern via an Objective-C block, courtesy of some glue API provided by MPWDrawingContext.


        NSSize patternSize=NSMakeSize(16,16);
        id diamond = [context laterWithSize:patternSize
                              content:^(id  context){
            id red = [context colorRed:1.0 green:0.0 blue:0.0 alpha:1.0];
            [context setFillColor:red];
            [[context moveto:patternSize.width/2 :2] 
				lineto:patternSize.width-2 :patternSize.height/2];
            [[context lineto:patternSize.width/2 :patternSize.height-2]
				lineto:2 :patternSize.height/2];
            [[context closepath] fill];
        }];
        [context setFillColor:diamond];
        [[context nsrect:[[self view] frame]] fill];

The "laterWithSize:content:" message creates a callback object that not only encapsulates the block, but also implements a -CGColor method so the callback can be used directly as a color in -setFillColor:.

With all the graphics specified using pure geometry, CoreGraphics can now do its thing and automatically handle varying device resolutions, wether it's a retina display or a zoomable interface or even print, all without ever having to deal with the different resolutions in code. Although I haven't tested it, the code should also use less memory, because it doesn't create potentially large temporary bitmaps, and for the cherry on top it's also a fraction of the code. CoreGraphics rules!

Forked project on github.

Saturday, October 13, 2012

Time for an Objective-C web framework?

More good news for Objective-C weenies like myself from the programming language popularity front: since we last checked in January of this year, Objective-C has now not only leapfrogged C# (now 50% above!), but even managed to edge out C++ and maintain that edge for 4 months. Amazing times, especially for us stealth-marketing hardened NeXTies.

With Ruby now at about 20% of the Objective-C popularity ratings (whatever those mean), maybe there is room to extend the Objective-C stack to the web? Especially as we are experiencing a shift in technologies from MVC frameworks to REST backends.

After all, we had this in the past, with core object models bridged to the UI with AppKit, to legacy databases with EOF and to the web with WebObjects. Now we could do mobile, desktop and server with a common, well-tested object model. Some say crafting object models this way is a Good Idea™. Thoughts?

Tuesday, June 12, 2012

A Pleasant Objective-C Drawing Context

In a recent post, Peter Hosey muses On the API design of CGBitmapContextCreate and apparently finds it somewhat lacking. Apart from agreeing violently, I'd extend that not just to the rest of CoreGraphics, but really to the state of drawing APIs in OSX and iOS in general.

On OSX, we have the Cocoa APIs, which are at least somewhat OO, but on the other hand don't have a real graphics context, only the stunted NSGraphcisContext which doesn't actually allow you to do, you know, graphics. Instead we have a whole bunch of "use-once" objects that are typically instantiated, told to draw themselves to an implicit global drawing context and then discarded. This seems exactly backwards, I would expect an explicit graphics context that I can use to draw using a consolidated API.

That consolidated API is only available in the form of the CGContextRef and its associated functions, but alas that's a C API. So extremely long names, but without named parameters or useful polymorphism. Despite the fact that a graphics context is a quintessential example of OO, only Apple can create subclasses of a CGContext, and even then in only a sorta-kinda sort of way: CGBitmapContextCreate returns a CGContextRef that silently knows how to do things that other CGContextRefs do not. Same for CGPDFContextCreate.

On iOS, CoreGraphics is really your only choice, and double so if you want code that works on both iOS and OSX, but that means having to put up with the API, constantly converting between UI/NS objects and CoreGraphics and then there's the whole text mess.

Having been a great fan of algorithmic drawing every since my exposure to DisplayPostscript on the NeXT Cube, I found all of this sufficiently unsatisfactory that I decided to work on a solution, the first step of which is a lightweight drawing context that provides a reasonable Objective-C drawing API on top of CoreGraphics and works the same on OSX and iOS.

The result is on github: MPWDrawingContext, embedded in a version of Mark Gallagher's excellent IconApp AppKit drawing example. The same code is also used in the iOS target (a variant of Marcus Crafter's version of IconApp). I've also started using the context in a bunch of my own projects (that was the purpose after all) and so far it's made my graphics coding much more pleasant.

Another advantage, at least for me, is that bridging to scripting languages is automatic due to Objective-C's runtime information, whereas C functions have to have to be bridged separately and maintained, which is burdensome and doesn't necessarily get done.

At least one of Peter's problem with CGBitmapContextCreate is also solved: creating a bitmap context is as easy as

    [MPWCGDrawingContext rgbBitmapContext:NSMakeSize(595,842)]
Last not least: although it wasn't an explicit goal, there is also a pleasant reduction in code bulk.
LinesCharactersLines %Characters %
AppKit146659367.12%76.69%
CGContext134736773.13%68.63%
MPWDrawingContext985056--

Saturday, May 12, 2012

Found another reason for code signing to fail

I usually only build in Release mode, even when developing, both because of potential differences between release and debug modes and because of difficulties with dependencies in Xcode. I was always a little worried that this would bite me, especially with iOS, because here Release means building for distribution, right?

Surprisingly, it never did, until I installed an Xcode upgrade just now. Suddenly, my in-development iPad app stopped building for my attached device (development mode). The error was

"warning: Application failed codesign verification. The signature was invalid, contains disallowed entitlements, or it was not signed with an iPhone Distribution Certificate. (-19011)"
After doing all the usual certificate song-and-dance routines, I finally figured out that a flag was (now?) set in the build settings: "Validate Build Product", which was set to "Yes" for "Release" and "No" for "Debug".

Never having seen it before, I can't say wether the setting itself had changed or something in the environment, but setting it to "No" for "Release" as well fixed the problem.

Sunday, April 8, 2012

Why Testing Matters for Performance

While performance certainly matters for testing, due to fast tests not breaking the feedback cycle that's so important in being agile (rather than "Doing Agile", which just isn't the same thing), the reverse is also true: with a trusted set of unit tests, you are much more likely to show the courage needed to make bold changes to working code in order to make it go faster.

So performance and testing are mutually dependent.

Friday, March 30, 2012

Why Performance Matters for Testing

While speed certainly matters in a production/e-commerce environment, I think it also is a significant factor for unit testing and especially TDD. While my tests haven't been tuned and certainly aren't the fastest in the world, my frameworks do test themselves in around 3 seconds using at present pretty much exactly 1000 tests.

That level of performance makes testing qualitatively different from having tests that run in 7 minutes down from 15 after some serious performance tuning described in the article, or 5 minutes down from 10. It means running the unit tests can be a normal part of edit-compile-run cycle, rather than a separate activity, supporting the idea that the tests are simply an intrinsic part of the code.

These are not lightweight tests, for example setting up and tearing down Postscript interpreters or running PDF and Postscript documents through text extraction engines. However, they do run in memory almost exclusively and mostly in a compiled language.

However, even 3 seconds is still too long a delay, feedback should be instantaneous to give a true interactive programming experience, or at least not get in the way of that experience. I saw a nice approach to this at the Hasso Plattner Institute using code coverage analysis to interactively run tests sorted by relevance to the code being edited (in Smalltalk). A simpler approach might be to just run the unit tests in the background while editing.

Wednesday, March 28, 2012

Three Kinds of Agile

Wiliam Edwards writes that Agile Is a Sham. He got quite a few intelligent comments, including those pointing out that the values he espouses are exactly those from the Agile Manifesto:

Individuals and interactions over processes and tools
Working software over comprehensive documentation
Customer collaboration over contract negotiation
Responding to change over following a plan

In my working life, I have encountered "Agile" three times. The last time was at a startup based in Oakland. It was Scrum, it was imposed from the top, a tool was introduced first in order to do agile tracking and planning, none of the actual technical practices were ever seriously considered. In short, exactly the kind of sham that Wiliam complains about. It had zero benefit.

Before that, we had two groups at BBC News Interactive starting to do their respective interpretations of XP. One did the simplest thing that could possibly work, for example never getting around to ever putting in the database, and did that in a test-first style. It didn't do standup meetings, paired at times, and every once in a while did a planning game. This team replaced a system that failed almost every single day and had abysmal performance using a 12 computer setup with a system that had two failures in 3 years, performed 100-1000 times better using only a single machine. The second team did standup meetings and planning games, but never managed to implement the technical practices such as TDD or DTSTTCPW/YAGNI. This team failed to deliver and the project was canceled/reset.

Finally, I first encountered what I would now recognize as XP before I knew that XP existed. Hard core YAGNI/DTSTTCPW, mixing pairing and working alone both organically and usefully. We introduced unit testing later and I became an immediate convert, having been responsible for shipping this product for some time and feeling the uncertainty over the question "when will it be ready". I later discovered that a bundle of these practices that we as coders had discovered for ourselves were known as XP, and I eagerly learned what I could from their experience.

So is Agile a sham? Maybe the dadaist manifesto put it best: if you are against this manifesto, you are a dadaist!

Tuesday, March 27, 2012

CocoaHeads Berlin Performance Talk

Last Wednesday, March 21st 2012, I held a talk on Cocoa Performance at the monthly Berlin CocoaHeads meeting. Thanks to everyone for the kind reception and benignly overlooking the fact that the end of the talk was a bit hurried.

Although the slides were primarily supportive and do not necessarily stand on their own, they are now available online by popular request (2.3MB, Keynote).

And a PDF version (6.3MB).

30k requests/s, aka wrk is fast

I just discovered wrk, a small and very fast http load testing tool. My previous experiments with µhttp-based MPWSideWeb first maxed out at around 5K requests per second, and after switching to httperf, I got up to around 10K per second. Using wrk on the same machine as previously, I now get this:
marcel@nomad[~]wrk  -c 100 -r 300000 http://localhost:8082/hi
Making 300000 requests to http://localhost:8082/hi
  2 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     4.60ms    2.51ms  11.47ms   62.40%
    Req/Sec    14.98k     0.99k   16.00k    52.80%
  300002 requests in 9.71s, 21.46MB read
Requests/sec:  30881.96
Transfer/sec:      2.21MB
marcel@nomad[~]curl http://localhost:8082/hi
Hello World!


So a nice 30K requests per second on a MacBook Air, and wrk was only running at around 60% CPU, whereas httperf tended to be pegged at 100%. The web-server in question is a minimal server like sinatra.rb set up to return a simple "Hello world!".
marcel@localhost[scripts]cat memhttpserver.stsh 
#!/usr/local/bin/stsh
context loadFramework:'MPWSideWeb'
server := MPWHTTPServer new.
server setPort: 8082.
stdout println: 'memhttpserver listening on port ',server port stringValue.
server start:nil.

scheme:base := MPWSiteMap scheme.
base:/hi := 'Hello World!'.
server setDelegate: scheme:base .

shell runInteractiveLoop

marcel@localhost[scripts]./memhttpserver.stsh 
memhttpserver listening on port 8082
>

So I definitely have a new favorite http performance tester!

30k entries (II), aka computers have RAM, and they can do I/O, too...

Let's assume a document storage system with an assumed maximum working set of 30K documents. Let's also assume we want to store some tags, maybe 10 per document, encoded as 32 bit integers (8 bits tag type, 24 bits tag value used as an index). That would be:
    30K documents x 10 tags/document x 4 bytes/tag = 
                           300K tags x 4 bytes/tag =
                                      1200 K bytes = 1.2 MB
Even assuming 2:1 bloat due to to overhead gives us 2.4 MB, which should not just fit comfortably into the RAM of a modern computer or a cellphone, it actually fits comfortably into the L3 cache of an Intel Core i7 with 8-10MB to spare.

What about getting that data into RAM? The slowest hard drives (non-SSD) I could find using a quick web search had a transfer rate of better than 48MB/s and a seek time of around 10ms, so the 2.4MB in question should be in memory in around:

 10ms + 2.4MB / (48MB/s) = 
           10ms + 0.05 s =
           10ms +  50 ms =  60 ms
So less than 1/10th of a second to read it in, and a moderately fast SSD reduces that to 10ms.

EDIT: fixed embarrassing typo (L1 -> L3 cache).

30k entries (I), aka computers are fast

Let's assume a document storage system with an assumed maximum working set of 30K documents. Let's say we want to assign tags to documents and search based on those tags, with an average of 10 tags per document. Using the most brain-dead algorithm available, linear scan of the document entries and string comparison on the tags, what would it take to search through those documents? Could we maintain immediate feedback?

Measuring quickly on my laptop reveals that strcmp() takes around 8ns for a long matching string and 2ns for a non-match in the first character (with first character optimization). Splitting the difference and thus not taking into account that non-matches tend to be more common than matches, let's assume 5ns to compare each tag.

 5ns /tag x 10 tags / document x 30k documents = 
               50ns / document x 30K documents = 
                                      1500K ns =  
                                       1500 µs = 1.5 ms
So an approach that takes longer than, say, 2ms to do such a search can probably be improved.

Of course, we could do something slightly less thoroughly braindead and represent tags using integer, er, tags. A simple integer comparison should be less then one nanosecond, so that would drop the time to below 300 µs. With that, we could do 3000 queries per second, or 300 queries every tenth of second (the generally accepted threshold for interactive performance).

In theory, we could actually start optimizing ever so slightly by storing lists of document ids with each tag and then simply doing set operations on the document lists stored with each tag. But we don't really have to.

Thursday, February 16, 2012

radr:10876615 Allow signed binaries on iOS

Summary: OS X 10.8 Mountain Lion has a setting to allow binaries to be installed that are signed by registered developers. Please add this feature to iOS.

Filed as 10876615

Wednesday, January 11, 2012

Objective-C language of the year 2011!

After just barely missing out 2 years in a row (first to Go and then to Python), Objective-C finally managed to snatch Tiobe's programming language of the year award for 2011. Yay!

Objective-C managed a jump of 3.91% to 6.92% in 2011, and is now only a percent or so shy of C++ (8.06%), which incidentally just got edged out by C# (8.78%). It also zoomed ahead of Python (3.22%), which squeaked by Objective-C just barely last year to take top honors, but has now fallen below PHP and Visual BASIC.

Ruby, Perl and JavaScript are in the 1-3% range.

As TIOBE doesn't appear to keep old posts around the above link is likely to go stale in about a month. Here is the table:

Position

Jan 2012

Position

Jan 2011

Delta in Position

Programming Language

Ratings

Jan 2012

Delta 

Jan 2011

Status

1

1

Same.gif

Java

17.479%

-0.29%

  A

2

2

Same.gif

C

16.976%

+1.15%

  A

3

6

Up.gifUp.gifUp.gif

C#

8.781%

+2.55%

  A

4

3

Down.gif

C++

8.063%

-0.72%

  A

5

8

Up.gifUp.gifUp.gif

Objective-C

6.919%

+3.91%

  A

6

4

Down.gifDown.gif

PHP

5.710%

-2.13%

  A

7

7

Same.gif

(Visual) Basic

4.531%

-1.34%

  A

8

5

Down.gifDown.gifDown.gif

Python

3.218%

-3.05%

  A

9

9

Same.gif

Perl

2.773%

-0.08%

  A

10

11

Up.gif

JavaScript

2.322%

+0.73%

  A

11

12

Up.gif

Delphi/Object Pascal

1.576%

+0.29%

  A

12

10

Down.gifDown.gif

Ruby

1.441%

-0.34%

  A

13

13

Same.gif

Lisp

1.111%

+0.00%

  A

14

14

Same.gif

Pascal

0.798%

-0.12%

  A

15

17

Up.gifUp.gif

Transact-SQL

0.772%

+0.01%

  A

16

24

Up.gifUp.gifUp.gifUp.gifUp.gifUp.gifUp.gifUp.gif

PL/SQL

0.709%

+0.15%

  A

17

20

Up.gifUp.gifUp.gif

Ada

0.634%

-0.05%

  B

18

39

Up.gifUp.gifUp.gifUp.gifUp.gifUp.gifUp.gifUp.gifUp.gifUp.gif

Logo

0.632%

+0.29%

  B

19

25

Up.gifUp.gifUp.gifUp.gifUp.gifUp.gif

R

0.609%

+0.07%

  B

20

21

Up.gif

Lua

0.559%

-0.08%

  B

And the graph: Tpci trends January 2012