1

I found that accessing Dictionary and Multi-Dimension array can be slow-- quite a puzzle since access time for dictionary and array is O(1).

This is my code

public struct StateSpace
{
public double q;
public double v;
public double a;
}

public class AccessTest
{
   public Dictionary<int, Dictionary<double,StateSpace>> ModeStateSpace;
   public double[,] eigenVectors;
   public void AccessJob(int n, double times)
  {
     var sumDisplacement = new double[6];
     for(int i=0; i< n; i++)
     {
       var modeDisplacement = ModeStateSpace[i][times].q;  //takes 5.81 sec
       for(int j=0; j<6; j++)
       {
                var eigenVector = eigenVectors[i, j];  //takes 5.69 sec
                sumDisplacement[i] += eigenVector*modeDisplacement ; //takes 1.06 sec        
       } 
     }
  } 



}

Notice the interesting part? The manipulation takes ~ 1 sec, but the accessing of dictionary and multi dimensional array takes ~5 sec!! Any idea why this is the case?

The n is not important here, and so is the absolute magnitude of the time needed for each operation. What is important is the ratio between the arithmetic operation and the dictionary lookup time.

Edit: I'm using Ants Profiler to do the profiling.

Note: I just simplified my actual code into something like this; the above code snippet has not been tested yet, but I'm fairly confident that I capture the gist of the problem with the above code snippet.

Graviton
  • 81,782
  • 146
  • 424
  • 602
  • you sure it's not the array dereferencing that is taking the time? – Mitch Wheat Oct 22 '10 at 03:24
  • @Mitch, this is c#, it's not C, so I don't think dereferencing matters. – Graviton Oct 22 '10 at 03:37
  • @Ngu: it does. Lookup locality of reference – Mitch Wheat Oct 22 '10 at 03:38
  • how are you obtaining the times, and what does the test data look like? – Les Oct 22 '10 at 03:50
  • @Less, I'm using Ants Profiler. The test data, it's about ~10k. – Graviton Oct 22 '10 at 03:56
  • @Ngu : Is collisions in dictionary not a problem? – TalentTuner Oct 22 '10 at 04:46
  • @saurabh, the collisions are not a problem – Graviton Oct 22 '10 at 05:51
  • 10k test data doesn't really mean anything, how many entries are there in `ModeStateSpace`, how many sub entries does each have, how many entries are there in `eigenVectors` and how big is `n` when this method is called?` – cjk Oct 22 '10 at 07:09
  • @ck, does the size of the dictionary *really* matter? I thought dictionary ( array) lookup should be an `O(1)` function, which means that it is independent of the collection size? Also, the `n` is not important, what is important is the relative magnitude between the arithmetic operation and the dictionary lookup time. – Graviton Oct 22 '10 at 07:30
  • The `n` *is* important as it tells you how many times you are iterating. The time you are reading is the total time for the execution of that line of code across **all** iterations, so if n is 5,000,000, then it is taking only a millisecond on that line each time. Also a dictionary lookup *will* be slower for a larger dictionary and the index grows. It's not linear, but may not be insignificant if the dictionary is large enough. – cjk Oct 22 '10 at 07:46
  • @ck, as I said ( maybe I didn't put it clearly when I formulated the question), what is **really** important is the *ratio* between the arithmetic operation vs. dictionary lookup ( about 5 to 1). I would expect a smaller ratio!!! And as for the dictionary lookup time grows with number of data,you have any reference on that? And even if dictionary lookup time does grow, what about the multi-dimension array access time? It's still awfully long compare to the arithmetic operation! – Graviton Oct 22 '10 at 07:55

1 Answers1

1

It is a known fact that jagged arrays are faster than multidimensional arrays in .NET (at least on windows):

Community
  • 1
  • 1
Ohad Schneider
  • 36,600
  • 15
  • 168
  • 198