views:

382

answers:

4

I've got a situation where I have a business object with about 15 properties of different types. The business object also has to implement an interface which has the following method:

object GetFieldValue(string FieldName);

I can see 2 ways of implementing this method:

Use a switch statement:

switch ( FieldName )
{
    case "Field1": return this.Field1;
    case "Field2": return this.Field2;
    // etc.
}

Use a dictionary (SortedDictionary or HashTable?):

return this.AllFields[FieldName];

Which would be more efficient?

Added: Forgot to say. This method is for displaying the item in a grid. The grid will have a column for each of these properties. There will routinely be grids with a bit over 1000 items in them. That's why I'm concerned about performance.

Added 2:

Here's an idea: a hybrid approach. Make a static dictionary with keys being property names and values being indices in array. The dictionary is filled only once, at the startup of the application. Every object instance has an array. So, the lookup would be like:

return this.ValueArray[StaticDictionary[FieldName]];

The dictionary filling algorithm can use reflection. The properties itself will then be implemented accordingly:

public bool Field1
{
    get
    {
        object o = this.ValueArray[StaticDictionary["Field1"]]; 
        return o == null ? false : (bool)o;
    }
    set
    {
        this.ValueArray[StaticDictionary["Field1"]] = value;
    }
}

Can anyone see any problems with this?

It can also be taken one step further and the ValueArray/StaticDictionary can be placed in a separate generic type ValueCollection<T>, where T would specify the type for reflection. ValueCollection will also handle the case when no value has been set yet. Properties could then be written simply as:

public bool Field1
{
    get
    {
        return (bool)this.Values["Field1"];
    }
    set
    {
        this.Values["Field1"] = value;
    }
}

And in the end, I'm starting to wonder again, if a simple switch statement might not be both faster and easier to maintain....

A: 

why not using reflection?

see this

A blog about reflection and performance

Another good article about reflection

Fredou
Shouldn't that be slower than either of these?
Vilx-
is performance, in millisecond, important?
Fredou
The object will be displayed in a grid which will query the properties. I'll routinely have about 1000 items in such a grid. That's 15'000 reflection calls. I shudder to think what would happen if each of them took 1ms.
Vilx-
ho, ok that is pretty big maybe reflection is not a good option in your case
Fredou
+10  A: 
switch:      good efficiency, least maintainable
dictionary:  good efficiency, better maintainability
reflection:  least efficient, best maintainability

Hint: ignore efficiency and worry about maintainability only, unless you've actually tested performance and found it be be an issue.

I'm not saying reflection is your only choice, just that it would allow you to add/remove and rename properties as needed, and not need to keep the switch statement or dictionary in sync.

Ash
Are you sure?
Vilx-
Hmm... well... ok...
Vilx-
Reflection would allow your properties to be discovered at run-time and so if you add/delete or rename any, you don't need to re-write any other code (such as the switch statement or dictionary initialisation).
Ash
I tend to find the cognitive overhead of reflection makes it somewhat less maintainable than the dispatch-table Dictionary approach. Though that may just be because I don't use reflection very often. :)
Greg D
A dictionary more efficient than a switch statement? I didn't expect that, could you elaborate?
Bubblewrap
@Bubblewrap. It could be for strings. For less sparse lookups a switch will be faster.
Mike Two
@Bubblewrap, I was almost going to write "equal efficiency" for switch and dictionary, but I'm just taking a general view that memory access at near O(1) is quicker then what the runtime can do with a switch lookup. This is exactly why I'm emphasizing the maintainability. I might change the wording anyway.
Ash
I modified the question a bit. Still think that reflection is the way to go?
Vilx-
@Greg, good point. Reflection isn't that hard, you just need to get familiar with the general "object tree" and how to navigate around it. What I do though is encapsulate reflection code into helper attribute classes that you can then utilise by simply adding atributes to your code.
Ash
@Vilx, as I'm comfortable with Reflection, I'd simply compare it with the dictionary or switch (using the Stopwatch class) and then decide. Yes, 15,000 calls to a version of GetFieldValue() that uses reflection may be a performance issue, but you need to confirm it is.
Ash
@Vilx, many domain/business object frameworks such as CSLA.NET allow you to "turn on/off" Reflection to enumerate object properties for exacylt the situation you describe (showing a grid).
Ash
OK, I'll profile it. It's true - for maintenance reflection is the easiest way (I'm comfortable with it too). But I really think it might easily eat up a couple of seconds while the grid opens up. Something I'd like to avoid.
Vilx-
Btw - maybe you could comment on my ramblings that I just added in the topic? :)
Vilx-
@Vilx, your hybrid approach would work in theory, but you're absolutely right about the extra maintainability issues it could introduce. I'd probably go with the simple dictionary or switch approach. The hybrid approach would be starting to "reinvent the wheel" in that other frameworks (CSLA) do tat sort of thing for you.
Ash
My application is pretty lightweight and I don't want to introduce ORM frameworks or the like. Especially because the data I'm visualing does not come in a neat tabular format from a RDBMS. However, the hybrid dictionary above should be superior to a simple dictionary in every aspect, including maintainability. The switch statement would be simpler though.
Vilx-
The switch will usually be the faster one not the dictionary (with few entries that is) Actually based on the overhead of calculating the hashkey I wouldn't feal confident that reflection wasn't faster than the dictionary (without testing at least)
Rune FS
Ash
Reflection is the devil
Faruz
+1  A: 

Because you are using strings Dictionary will probably be faster. Switch will essentially get translated to a hashtable when using strings. But if you are using ints or similar it gets translated to a jump table and will be faster.

see this answer and question for more details

Best bet is to profile it and find for sure

Mike Two
A: 

How you get the value of each property will probably have a lesser impact on the overall performance than how you render your grid.

Let me give you an example: let's say you have the following implementation:

private string _latestFieldName = string.Empty;
private PropertyInfo _propertyInfo;

object GetFieldValue(string FieldName)
{
  if(FieldName != _latestFieldName)
  {
    _propertyInfo = typeof(yourTypeName).GetProperty(FieldName);
  }
  return _propertyInfo.GetValue(this,null);
}

If your grid rendering is rendering a row at a time using reflection it will have to get the propertyinfo every single time. wheras if you render column by column you'd only have to get the propertyInfo once for each property and since the branch prediction will be right almost every time you'd only miss a very few clock cycles on the if. When you have the PropertyInfo already and you don't need to cast the result of the call to GetValue. using reflection comes VERY close to using the getter of a property when it comes to speed.

My point is before you start to optimize use a profiler. (Of course if you can't change the grid well you can't really optimize it either)

Rune FS
Nop, I can't change the grid. :)
Vilx-