3

I've a question about NSString internals. I want to check a string length and basically I wanted to know if a NSString knows its length / count each time / count & cache the result.

Should I store it's length and compute or call the length method each time ?

To test a string I can test against nil OR ask for it's length.

if (str != nil) {
  // compute
}

if ([str length]) {
  // compute
}

Which one is the fastest ? Which one is the more memory efficient ?

Thanks

adrian Coye
  • 173
  • 1
  • 14

5 Answers5

8

Checking for nil ("no object") is most definitely not the same as sending the length message to the (NSString) object. Only one of the conditional checks is valid to test for an "empty" string. (An "empty" string is an object and, therefore, not nil.)

The bigger question is: does NSString store a length or is it sentinel-terminated (like a "normal c string")? NSString stores the length as an internal property so it, length, is as O(1) operation.

Happy coding.

7

Here is how CFStringGetLength works:

(from http://opensource.apple.com/source/CF/CF-550.43/CFString.c)

/* Returns length; use __CFStrLength2 if contents buffer pointer has already been computed.
*/
CF_INLINE CFIndex __CFStrLength(CFStringRef str) {
    if (__CFStrHasExplicitLength(str)) {
        if (__CFStrIsInline(str)) {
                return str->variants.inline1.length;
        } else {
                return str->variants.notInlineImmutable1.length;
        }
    } else {
        return (CFIndex)(*((uint8_t *)__CFStrContents(str)));
    }
}

So it should be O(1) for all cases.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
sbooth
  • 16,646
  • 2
  • 55
  • 81
3

The two -- testing a NSString pointer for nil and testing the length of an NSString -- are not in any way equivalent. An NSString object with a zero length can exist, and a pointer to it will not compare equal to nil.

To my knowledge (and I'd be quite surprised to discover I was wrong), the length of an NSString is stored within the object as an efficiently-referenced property. Caching the length would generally be unnecessary complexity.

Hot Licks
  • 47,103
  • 17
  • 93
  • 151
1

NSString is immutable class, so the length stays the same all of the time.

MByD
  • 135,866
  • 28
  • 264
  • 277
1

Addendum: Testing against [string length] evaluates to 0/nil/NO in both cases (string being nil and string having zero length).

fzwo
  • 9,842
  • 3
  • 37
  • 57
  • That reminds me: I've always wondered, coming from both a Java and a Smalltalk background, what nil is, exactly. Is it a special class (like in Smalltalk, where there are no primitives, and everything (!) is an object), or just a constant that amounts to int 0? I suppose due to the c roots, 0, nil, NULL, NO, false are all the same - 0? – fzwo Jul 08 '11 at 21:46
  • 1
    `nil` is defined in [objc.h](http://opensource.apple.com/source/objc4/objc4-437.3/runtime/objc.h) as `__DARWIN_NULL`, which is defined in as `((void *)0)`. – jscs Jul 08 '11 at 22:10
  • 3
    @fzwo `nil` and `null` are special values that represent "no object". `nil` is the the sole inhabitant of the respective "none type": even with implementation detail leakage ("0/NULL"), it can be thought of as such. That is, `nil` is a value that can only mean one thing: "no object". [NULL vs nil](http://stackoverflow.com/questions/557582/null-vs-nil-in-objective-c) may be interesting as it shows that Objective-C really just is a layer on C/C++ ;-) [What I said above relies on the use of semantics.] –  Jul 08 '11 at 22:12