Question

quandry is - which of the following two method performs best
Goal - get an object of type Wrapper ( defined below )
criteria - speed over storage
no. of records - about 1000- about 2000, max about 6K
Choices - Create Object on the fly or do a lookup from a dictionary
Execution speed - called x times per second

NB - i need to deliver the working code first and then go for optimization hence if any theorists can provide glimpses on behind the scene info, that'll help before i get to the actual performance test possibly by eod thu

Definitions -

class Wrapper  
{  
   public readonly DataRow Row;  
   public Wrapper(DataRow dr)  
   {  
      Row = dr;  
   }  
   public string ID { get { return Row["id"].ToString(); } }  
   public string ID2 { get { return Row["id2"].ToString(); } }  
   public string ID3 { get { return Row["id3"].ToString(); } }  
   public double Dbl1 { get { return (double)Row["dbl1"]; } }  
   // ... total about 12 such fields !  
}  
Dictionary<string,Wrapper> dictWrappers;  

Method 1

Wrapper o = new Wrapper(dr);  
/// some action with o
myMethod( o );

Method 2

Wrapper o;    
if ( ! dictWrappers.TryGetValue( dr["id"].ToString(), out o ) )    
{    
    o = new Wrapper(dr);    
    dictWrapper.Add(o.ID, o);    
}    

/// some action with o    
myMethod( o );    
Was it helpful?

Solution

The first one would be faster, since it isn't actually doing a lookup, it is just doing a simple allocation and an assignment.

The two segments of code are not nearly equivalent. In function however, because Method 1 could create many duplicates.

OTHER TIPS

  1. Never optimize without profiling first.
  2. Never profile unless the code does not meet specifications/expectations.
  3. If you need to profile this code, write it both ways and benchmark it with your expected load.

EDIT: I try to favor the following over optimization unless performance is unacceptable:

  • Simplicity
  • Readability
  • Maintainability
  • Testability

I've (recently) seen highly-optimized code that was very difficult to debug. I refactored it to simplify it, then ran performance tests. The performance was unacceptable, so I profiled it, found the bottlenecks, and optimized only those. I re-ran the performance tests, and the new code was comparable to the highly-optimized version. And it's now much easier to maintain.

Here's a free profiling tool.

Without actually testing I would expect that caching the field values in Wrapper (that is, avoiding all the ToString calls and casts) would probably have more of an impact on performance.

Then once you are caching those values you will probably want to keep instances of Wrapper around rather than frequently recreate them.

Assuming that you're really worried about per (hey, it happens) then your underlying wrapper itself could be improved. You're doing field lookups by string. If you're going to make the call a lot with the same field set in the row, it's actually faster to cache the ordinals and look up by ordinal.

Of course this is only if you really, really need to worry about performance, and the instances where this would make a difference are fairly rare (though in embedded devices it's not as rare as on the desktop).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top