Skip navigation.
 
mlRe: Fwd: NSArray - waste of time?
FROM : Erik Buck
DATE : Fri Apr 27 17:02:13 2007

> I'd like to know more about this. I'm currently using C-style 
> arrays for
> storing 3D model data such as vertices, vertex indices, normals, 
> texture
> coordinates etc.
>
> Some of the models are large and naturally C-style arrays are the 
> optimal
> kind of array for this sort of thing, but as I'm also using Core 
> Data and
> shoving most things at the GPU and so iteration is less problematic 
> than if
> one were in immediate mode, and I'd quite like some of the 
> flexibility and
> security offered by NSArrays. Is using an NSArray of NSNumbers 
> realistic in
> this sense? I mean how big is an NSNumber object for instance, 
> considering
> there might be 100,000's of them?


Using NSArray of NSNumbers (or NSValue) is NOT a realistic way to 
store large amounts of data that is destined for use in OpenGL APIs 
[IMHO].

When using OpenGL vertex arrays and vertex buffers, it is absolutely 
key that the data in the vertex arrays and vertex buffers is stored 
for efficient transfer to and from the GPU.

Here is a rationale: You wouldn't store the RGBA values for every 
individual pixel in an image as an giant NSArray of NSNumbers.  So 
why would you store vertices, vertex indices, normals, and texture 
coordinates in a giant NSArray of NSNumbers ?  For an OpenGL API 
perspective, there is effectively no difference between a vertex 
array and an array of RGB values.

As it happens, I have written a lot of OpenGL code mixed with Cocoa. 
I usually use the NSData class to store vertices, vertex indices, 
normals, and texture coordinates.  NSData enables byte oriented 
access to the contained data and is well suited for use with OpenGL 
APIs.  NSData also provides many of the Cocoa advantages including 
storage in Core Data, memory management, archiving and un-archiving, 
etc.  NSMutableData automatically grows to accommodate more data too.

Just for reference:
A) The minimum storage needed to use an Objective-C object instance 
is 8 bytes for use: 4 bytes for the required isa pointer and 4 bytes 
for the pinter to the instance.
e.g id fubar = [[NSObject alloc] init]; // 4 bytes for fubar and 4 
bytes for fubar->isa.

B) Most objects including NSNumber need at least another 4 bytes to 
store anything interesting.
e.g. id fubar = [[NSNumber alloc] initWithInt:10]; // 4 bytes for 
fubar and 4 bytes for fubar->isa 4 bytes for fubar->value
Note: Common NSNumber instances may be cached and reused thus 
reducing aggregate memory needs somewhat.

C) Any instance of a subclass of NSObject will typically require an 
additional 8 bytes if its reference count is not 1.  The extra 8 
bytes are used by a hash table that stores the reference count.  e.g. 
4 bytes for the hash key and 4 bytes for the associated reference count.

So far, an NSNumber instance that is not cached for reuse and has a 
retain count other than 1 requires a minimum of 20 bytes.

Now, storing NSNumber instances in an NSArray is essentially free 
because the 4 byte reference to each stored kept by NSArray 
presumably exists in stead of the fubar reference cites in A), B), 
and C) above.

id fubar = [[NSArray alloc] initWithObject:[NSNumber numberWithInt:47]];

4 bytes for fubar, 4 bytes for fubar->isa, 4 bytes for fubar->count, 
4 bytes for pointer to the array's internal storage (fubar->storage), 
4 bytes for the number's isa, 4 bytes for the number's value, 8 bytes 
for the numbers reference count if it isn't 1, 8 bytes for fubar's 
reference count if it isn't 1.

Grand total for an NSArray contain one NSNumber instance is between 
24 and 40 bytes depending on whether the objects have a retain count 
greater than 1 or not.

Now, having analyzed all that, most applications can afford to spend 
40 bytes on an NSArray containing an NSNumber.  As already stated in 
this thread, you get a lot of functionality for those 40 bytes.

Storing OpenGL primitive data for use in vertex arrays etc. is just 
not one of the applications that can afford spending 40 bytes instead 
of the 4 bytes that    int    array[1]  consumes.


See also http://www.mulle-kybernetik.com/artikel/Optimization/
opti-4.html

Related mailsAuthorDate
mlFwd: NSArray - waste of time? Soares Apr 27, 14:28
mlRe: Fwd: NSArray - waste of time? Erik Buck Apr 27, 17:02
mlRe: Fwd: NSArray - waste of time? Erik Buck Apr 27, 17:04