Fwd: NSArray - waste of time?

  • 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?

    F.

    On 26/04/07, Philippe Mougin <pmougin...> wrote:
    >
    >
    > It depends how the NSArrays you deal with are implemented (remember
    > that NSArray is a class cluster -- in other words, a semi-abstract
    > class). For instance, in F-Script we make extensive usage of NSArrays
    > (in particular arrays of NSNumbers), but we do so using an
    > implementation that transparently make them as small and as fast as C-
    > style arrays, in most cases.
    >
    > Philippe Mougin
    >
  • > 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
  • Here is a previous thread on the subject of mixing Core Data and OpenGL

    http://www.cocoabuilder.com/archive/message/cocoa/2007/2/22/179216
previous month april 2007 next month
MTWTFSS
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30            
Go to today