Ejemplo n.º 1
0
        private static void Run <T>(IIndex <int, TRectangle, TPoint> index, IList <Tuple <int, T> > data,
                                    BuildSmallUpdates <T> makeSmallUpdate,
                                    BuildLargeUpdates <T> makeLargeUpdate,
                                    AddEntries <T> addEntries,
                                    DoUpdate <T> doUpdate)
        {
            // Get new randomizer.
            var random = new MersenneTwister(Seed);

            // Get stop watch for profiling.
            var watch = new Stopwatch();

            // Also allocate the ids to look up in advance.
            var rangeQueries = new List <Tuple <TPoint, float> >(Operations);
            var areaQueries  = new List <TRectangle>(Operations);

            // And updates.
            var smallUpdates = new List <Tuple <int, T> >(Operations);
            var largeUpdates = new List <Tuple <int, T> >(Operations);

            var addTime              = new DoubleSampling(Iterations);
            var rangeQueryTime       = new DoubleSampling(Iterations);
            var areaQueryTime        = new DoubleSampling(Iterations);
            var smallUpdateTime      = new DoubleSampling(Iterations);
            var largeUpdateTime      = new DoubleSampling(Iterations);
            var highLoadRemoveTime   = new DoubleSampling(Iterations);
            var mediumLoadRemoveTime = new DoubleSampling(Iterations);
            var lowLoadRemoveTime    = new DoubleSampling(Iterations);

            Console.Write("Doing {0} iterations... ", Iterations);

            for (var i = 0; i < Iterations; i++)
            {
                Console.Write("{0}. ", i + 1);

                // Clear the index.
                index.Clear();

                // Generate look up ids in advance.
                rangeQueries.Clear();
                for (var j = 0; j < Operations; j++)
                {
                    rangeQueries.Add(Tuple.Create(random.NextVector(Area), MinQueryRange + (MaxQueryRange - MinQueryRange) * (float)random.NextDouble()));
                }
                areaQueries.Clear();
                for (var j = 0; j < Operations; j++)
                {
                    areaQueries.Add(random.NextRectangle(Area, MinQueryRange * 2, MaxQueryRange * 2));
                }

                // Generate position updates.
                smallUpdates.Clear();
                largeUpdates.Clear();
                for (var j = 0; j < Operations; j++)
                {
                    // High chance it remains in the same cell.
                    makeSmallUpdate(smallUpdates, data, random, j);
                }
                for (var j = 0; j < Operations; j++)
                {
                    // High chance it will be outside the original cell.
                    makeLargeUpdate(largeUpdates, data, random, j);
                }

                // Test time to add.
                try
                {
                    watch.Reset();
                    watch.Start();
                    addEntries(index, data);
                    watch.Stop();
                    addTime.Put(watch.ElapsedMilliseconds / (double)NumberOfObjects);
                }
                catch (NotSupportedException)
                {
                }

                // Test update time.
                try
                {
                    watch.Reset();
                    watch.Start();
                    foreach (var update in smallUpdates)
                    {
                        doUpdate(index, update);
                    }
                    watch.Stop();
                    smallUpdateTime.Put(watch.ElapsedMilliseconds / (double)smallUpdates.Count);
                }
                catch (NotSupportedException)
                {
                }

                try
                {
                    watch.Reset();
                    watch.Start();
                    foreach (var update in largeUpdates)
                    {
                        doUpdate(index, update);
                    }
                    watch.Stop();
                    largeUpdateTime.Put(watch.ElapsedMilliseconds / (double)largeUpdates.Count);
                }
                catch (NotSupportedException)
                {
                }

                // Test look up time.
                try
                {
                    watch.Reset();
                    watch.Start();
                    for (var j = 0; j < Operations; j++)
                    {
#if USE_CALLBACK
                        index.Find(rangeQueries[j].Item1, rangeQueries[j].Item2, value => true);
#else
                        index.Find(rangeQueries[j].Item1, rangeQueries[j].Item2, ref DummyCollection <int> .Instance);
#endif
                    }
                    watch.Stop();
                    rangeQueryTime.Put(watch.ElapsedMilliseconds / (double)Operations);
                }
                catch (NotSupportedException)
                {
                }

                try
                {
                    watch.Reset();
                    watch.Start();
                    for (var j = 0; j < Operations; j++)
                    {
                        var rect = areaQueries[j];
#if USE_CALLBACK
                        index.Find(rect, value => true);
#else
                        index.Find(rect, ref DummyCollection <int> .Instance);
#endif
                    }
                    watch.Stop();
                    areaQueryTime.Put(watch.ElapsedMilliseconds / (double)Operations);
                }
                catch (NotSupportedException)
                {
                }

                // Test removal time.
                try
                {
                    watch.Reset();
                    watch.Start();
                    for (var j = 0; j < NumberOfObjects / 3; j++)
                    {
                        index.Remove(data[j].Item1);
                    }
                    watch.Stop();
                    highLoadRemoveTime.Put(watch.ElapsedMilliseconds / (double)(NumberOfObjects / 3));
                }
                catch (NotSupportedException)
                {
                }

                try
                {
                    watch.Reset();
                    watch.Start();
                    for (var j = NumberOfObjects / 3; j < NumberOfObjects * 2 / 3; j++)
                    {
                        index.Remove(data[j].Item1);
                    }
                    watch.Stop();
                    mediumLoadRemoveTime.Put(watch.ElapsedMilliseconds / (double)(NumberOfObjects / 3));
                }
                catch (NotSupportedException)
                {
                }

                try
                {
                    watch.Reset();
                    watch.Start();
                    for (var j = NumberOfObjects * 2 / 3; j < NumberOfObjects; j++)
                    {
                        index.Remove(data[j].Item1);
                    }
                    watch.Stop();
                    lowLoadRemoveTime.Put(watch.ElapsedMilliseconds / (double)(NumberOfObjects / 3));
                }
                catch (NotSupportedException)
                {
                }
            }

            Console.WriteLine("Done!");

            Console.WriteLine("Operation           | Mean      | Std.dev.\n" +
                              "Add:                | {0:0.00000}ms | {1:0.00000}ms\n" +
                              "Range query:        | {2:0.00000}ms | {3:0.00000}ms\n" +
                              "Area query:         | {4:0.00000}ms | {5:0.00000}ms\n" +
                              "Update (small):     | {6:0.00000}ms | {7:0.00000}ms\n" +
                              "Update (large):     | {8:0.00000}ms | {9:0.00000}ms\n" +
                              "Remove (high load): | {10:0.00000}ms | {11:0.00000}ms\n" +
                              "Remove (med. load): | {12:0.00000}ms | {13:0.00000}ms\n" +
                              "Remove (low load):  | {14:0.00000}ms | {15:0.00000}ms",
                              addTime.Mean(), addTime.StandardDeviation(),
                              rangeQueryTime.Mean(), rangeQueryTime.StandardDeviation(),
                              areaQueryTime.Mean(), areaQueryTime.StandardDeviation(),
                              smallUpdateTime.Mean(), smallUpdateTime.StandardDeviation(),
                              largeUpdateTime.Mean(), largeUpdateTime.StandardDeviation(),
                              highLoadRemoveTime.Mean(), highLoadRemoveTime.StandardDeviation(),
                              mediumLoadRemoveTime.Mean(), mediumLoadRemoveTime.StandardDeviation(),
                              lowLoadRemoveTime.Mean(), lowLoadRemoveTime.StandardDeviation());
        }