views:

51

answers:

3

Uhm, so I had problems with the title, but this was my best shot!

Situation: I am writing a library so that I easily can re-use my code in future projects, without thinking about the internals. This library is supposed to be able to create objects at runtime and then access them to do tasks via a method. All by using a easy-to-use identifier.

Something like this:

class Manager
{
    Object[] Foo;
    // Other stuff + initialization logic

    CreateFoo(/*Some parameters here + Identifier*/)
    {
        // Create a new Foo here;
    }
    AddBar(/*Moar parameters + Foo identifier*/)
    {
        Foo[StoID(identifier)].AddBar(/*Params*/);
    }

}

class Software
{
    Software()
    {
        // Create a lot of Foos.
        while(1)
        {
             manager.CreateFoo(/*Params*/);
        }
    }
    void OhHai()
    {
        // This method can be called a LOT (100 times per update) or not at all       
        // depending on circumstances.
        manager.AddBar(/*Params*/);
    }
}

Disclaimer: No, that is NOT actually my code silly!

Problem: I might want to access my Foo Objects a lot and the performance is crucial, but so is manageability and ease of use. My first thought, for example, was to use strings and array indexes to create a small, dynamic conversion-library. However this would mean a lot of iterations - depending on how many Foos are created - and string-comparing.

Example:

class Software
{
    Manager manager;
    Software()
    {
        manager.CreateFoo("Lol", /*Parameters*/);
        manager.CreateFoo("Cat", /*Parameters*/);
    }
    void OhHai()
    {
        manager.AddBar("Lol", /*Parameters 1*/;
        manager.AddBar("Cat", /*Parameters 2*/;
    }
}

The performance of directly accessing a Foo with an index must be far greater than first converting a string to id. However strings are easily managed by humans so ease of use would be perfect that way.

What I'm asking: How are these things usually handled and does anyone have a suggestion for how I should design this?

Edit: Basically I'm trying to find an easy way for my manager to know which Foo to add a Bar to! :)

+2  A: 

I might be missing something here, but it looks like what you want to use as your backing store is a Dictionary object instead of Arrays.

The time to index into a dictionary is O(1). You can't be constant time. :)

Well, you can if your constant time is REALLY long, but it's not for dictionary retrieval. Just make sure your GetHashCode method produces a good hash and you should be golden.

CubanX
Well, isn't the Dictionary just basically comparing strings? (Didn't know about the Dictionary until now) How is the performance implications of this? :\
Robelirobban
No, the dictionary is using a hash-table (it's a generic hashtable implementation). That being said, hashtables are O(n), but on average they perform as good as 1.2 steps per retrieval (remember Big-O is the "worse than the worst case").
Tamás Szelei
Aah, learned some great stuff today too, thanks to you guys! :) Using a dictionary definitely was useful, thus this question is answered :)
Robelirobban
@sztomi According to MS, on the Dictionary class help page: http://msdn.microsoft.com/en-us/library/xfhwa508.aspx Retrieval is O(1). Relevant section is under the Remarks."Retrieving a value by using its key is very fast, close to O(1), because the Dictionary<TKey, TValue> class is implemented as a hash table."Again, the assumption is your Hashing algorithm doesn't produce a lot of identical hashes. If you do very bad hashing, then yes, you can approach O(n).
CubanX
@sztomi Also, big O is NOT "worse than the worst case". It can be used to describe any case. So for a simple linear search, worst case is O(n) (last item in list), best case is O(1) (first item in list), average case is O(n/2).Note the description in the wikipedia article: http://en.wikipedia.org/wiki/Big_o_notation
CubanX
A: 

Something about this approach smells... but that's just my opinion.

I think much of what you are trying to do could be accomplished with a DI framework like Spring.NET. It would allow you to create and inject objects into your code by a "friendly name" without worrying about their precise type (as long as they implement a certain interface or extend a certain base class).

Eric Petroelje
Well, changing framework is not an option. For the record, XNA is my framework. What I'm trying to do is to use a particular Foo's method CreateBar() to create a Bar. The problem is to access the Foo that I want to have the new Bar. I want it easy to do while still retaining performance - if possible.
Robelirobban
A: 

why don't you change your class here

class Manager
{
    Foo CreateFoo(/*Some parameters here + Identifier*/)
    {
        // Create a new Foo here AND return it
    }
    void AddFoo(Foo foo)
    {
     // adds to yor collection
    }
    AddBar(/*Moar parameters + Foo instance*/)
    {
        foo.AddBar(/*Params*/);
    }

}
Arseny
Because I need to be able to add a new Bar to any given Foo at any given time. Therefor I need access to a particular Foo at runtime. The problem isn't if it can be done, but how to do it easy while keeping performance up! :)
Robelirobban