Nat! bio photo

Nat!

Senior Mull

Twitter Github Twitch

mulle-objc: some research about selectors

Continued from mulle-objc: inlined messaging

This is a bit of research I’ve done concerning selectors and their use in Objective-C.

Selector usage statistics (static)

As it turns out about 75% of all selectors only take at most one parameter.

I wrote a script around class-dump that scraped all selectors known to my OS X system and collected them in a text file.

class-dump -r "$binary" | egrep '^[+-]' | sed 's/:([a-zA-Z0-9_^\<\>\*\ ]*)\ *arg[0-9]*\ */:/g' | sed 's/[+-]\ ([a-zA-Z0-9_^\<\>\*\ ]*)//g' | tr -d ';' | sort | sort -u  2> /dev/null

It found 234,365 unique selectors. Then I analyzed the file according to number of parameters:

sed 's/[^:]*\(:*\)/\1/g' | sort | uniq -c

Which resulted in 37% of all methods having no parameter, 39% having one parameter, 14% having two, 6% having three and so on (number of selectors is number of ‘:’):

87082
90603 :
32206 ::
13618 :::
 5782 ::::
 2549 :::::
 1228 ::::::
  564 :::::::
  323 ::::::::
  165 :::::::::
   88 ::::::::::
   57 :::::::::::
   31 ::::::::::::
   22 :::::::::::::
   14 ::::::::::::::
    9 :::::::::::::::
    8 ::::::::::::::::
    4 :::::::::::::::::
    7 ::::::::::::::::::
    1 :::::::::::::::::::
    1 ::::::::::::::::::::
    1 :::::::::::::::::::::
    1 ::::::::::::::::::::::
    1 :::::::::::::::::::::::

Selector usage statistics (dynamic)

As it turns out about 90% of all method calls are with selectors, that only take at most one parameter. (In a case study of one program)

I ran a CoreData enabled iOS 8 app that does a lot of drawing on the iPad. I dumped the method calls with the environment variable NSObjCMessageLoggingEnabled and analyzed the resultant 628 MB file in /tmp, which had logged 10,736,016 method calls.

cat msgSends-8598 | awk '{ print $4 }' | sort | uniq -c | sort -n -r | head -100

Here is the top 30 of a total of 11,274 used selectors in this application (when run in optimized mode with no assertions), which account for pretty much 50% of all method calls.

703,484 class
483,335 release
343,421 retain
300,315 dealloc
299,138 autorelease
294,309 characterAtIndex:
260,189 isEqual:
250,537 hash
228,409 allocWithZone:
197,911 alloc
195,324 count
179,983 length
171,437 objectForKey:
156,440 self
138,796 superview
130,172 init
117,794 isKindOfClass:
115,093 countByEnumeratingWithState:objects:count:
110,880 objectAtIndex:
103,901 lock
103,728 unlock
 66,753 immutablePlaceholder
 64,955 window
 64,917 layer
 63,389 traitCollection
 63,009 timeIntervalSinceReferenceDate
 62,291 copyWithZone:
 60,309 _frameDescriptor
 59,133 _viewDelegate
 52,389 mainScreen

Looks like someone is using characterAtIndex: and class way too much, and it isn’t me.

And here’s the analysis of the actually called selector arguments count spread:

6,882,106
2,865,942 :
  460,207 ::
  385,438 :::
   78,214 ::::
   47,753 :::::
   12,396 ::::::
    2,050 :::::::
      863 ::::::::::::::
      749 ::::::::
      134 :::::::::
      125 :::::::::::
       19 ::::::::::
       10 :::::::::::::::
       10 :::::::::::::

In a different run with 14,126,799 method calls, I counted 12,052,807 instance methods and 2,073,992 class methods. So instance methods were approximately 85% of all method calls.

Food for thought

  1. A selector is most likely to have one or two parameters.
  2. A method call is most likely to be an instance method call with zero or one parameter.
  3. Temporary object allocation seems to make up the bulk of method calls in a running program in iOS. But the number of calls is not necessarily an indication that most of the time is spent there.

Continued to mulle-objc: hashes for classes, selectors and protocols


Post a comment

All comments are held for moderation; basic HTML formatting accepted.

Name:
E-mail: (not published)
Website: