예제 #1
0
        public void CouldCalculateSMAWithWidthEQ()
        {
            Assert.Throws <NotImplementedException>(() =>
            {
                var count = 20;
                var sm    = new SortedMap <int, double>();
                sm.Add(0, 0);
                for (int i = 2; i <= count; i++)
                {
                    sm.Add(i, i);
                }
                sm.Remove(11);
                sm.Remove(12);
                var onlineOp = new SumAvgOnlineOp <int, double, SortedMapCursor <int, double> >();
                var smaOp    = new SpanOpWidth <int, double, double, SortedMapCursor <int, double>, SumAvgOnlineOp <int, double, SortedMapCursor <int, double> > >
                                   (2, Lookup.EQ, onlineOp);
                var smaSeries =
                    new SpanOpImpl <int,
                                    double,
                                    double,
                                    SpanOpWidth <int, double, double, SortedMapCursor <int, double>, SumAvgOnlineOp <int, double, SortedMapCursor <int, double> > >,
                                    SortedMapCursor <int, double>
                                    >(sm.GetEnumerator(), smaOp).Source;

                foreach (var keyValuePair in smaSeries)
                {
                    Trace.WriteLine($"{keyValuePair.Key} - {keyValuePair.Value}");
                }
            });
        }
예제 #2
0
        internal static Series <TKey, TValue, Range <TKey, TValue, SortedMapCursor <TKey, TValue> > > Range <TKey, TValue>(
            this SortedMap <TKey, TValue> series,
            Opt <TKey> startKey, Opt <TKey> endKey, bool startInclusive = true, bool endInclusive = true)
        {
            var cursor = new Range <TKey, TValue, SortedMapCursor <TKey, TValue> >(
                series.GetEnumerator(), startKey, endKey, startInclusive, endInclusive);

            return(cursor.Source);
        }
예제 #3
0
        public void CouldFillThenAddValues()
        {
            var sm = new SortedMap <int, double>
            {
                { 1, 0 },
                { 3, 2 },
                { 5, 4 }
            };



            var src     = (sm.GetEnumerator() as ISpecializedCursor <int, double, SortedMapCursor <int, double> >).Source;
            var filled  = src.Fill(0);
            var filled2 = (src as ISpecializedSeries <int, double, SortedMapCursor <int, double> >).Fill(0);
            var filled3 = sm.Fill(0);

            var fc = new Fill <int, double, Cursor <int, double> >(sm.GetSpecializedCursor(), 41).Initialize();
            var c  = (fc.Source + 1).GetEnumerator();

            Assert.True(c.MoveNext());
            Assert.AreEqual(1, c.CurrentValue);

            Assert.True(c.MoveNext());
            Assert.AreEqual(3, c.CurrentValue);

            Assert.True(c.MoveNext());
            Assert.AreEqual(5, c.CurrentValue);

            Assert.False(c.MoveNext());
            Assert.AreEqual(5, c.CurrentValue);

            Assert.True(c.MoveLast());
            Assert.AreEqual(5, c.CurrentValue);

            Assert.False(c.MoveAt(4, Lookup.EQ));
            Assert.AreEqual(5, c.CurrentValue);

            Assert.True(c.MoveAt(4, Lookup.LE));
            Assert.AreEqual(3, c.CurrentValue);

            Assert.True(c.TryGetValue(2, out var x));
            Assert.AreEqual(3, c.CurrentValue);
            Assert.AreEqual(42, x);

            var clone = c.Clone();

            Assert.True(c.MoveAt(4, Lookup.GT));
            Assert.AreEqual(5, c.CurrentValue);
            Assert.AreEqual(3, clone.CurrentValue);

            Assert.True(clone.TryGetValue(0, out var y));
            Assert.AreEqual(42, y);

            c.Dispose();
        }
예제 #4
0
        public void CouldAddTwoSeriesWithDifferentKeys()
        {
            var count = 10000;
            var sm1   = new SortedMap <int, double>();
            var sm2   = new SortedMap <int, double>();

            var    result   = new SortedMap <int, double>();
            double expected = 0;

            for (int i = 0; i < count; i++)
            {
                sm1.Add(i, i);
                if (i % 3 == 0)
                {
                    sm2.Add(i, 2 * i);
                    expected += i + 2 * i;

                    result.Add(i, i + 2 * i);
                }
            }

            for (int r = 0; r < 1; r++)
            {
                var c1        = sm1.GetEnumerator();
                var c2        = sm2.GetEnumerator();
                var zipCursor =
                    new Zip <int, double, double, SortedMapCursor <int, double>,
                             SortedMapCursor <int, double> >(
                        c1, c2).Initialize();

                double actual = 0;
                using (Benchmark.Run("ZipDiscrete MN", sm1.Count + sm2.Count))
                {
                    while (zipCursor.MoveNext())
                    {
                        actual += zipCursor.Map((k, v) => v.Item1 + v.Item2).CurrentValue;
                    }
                }
                Assert.AreEqual(expected, actual);

                zipCursor.Reset();
                actual = 0;
                using (Benchmark.Run("ZipDiscrete MP", sm1.Count + sm2.Count))
                {
                    while (zipCursor.MovePrevious())
                    {
                        actual += zipCursor.Map((k, v) => v.Item1 + v.Item2).CurrentValue;
                    }
                }
                Assert.AreEqual(expected, actual);
            }

            Benchmark.Dump();
        }
예제 #5
0
        public void CouldMapValuesBenchmark()
        {
            var sm    = new SortedMap <int, double>();
            var count = 10000000;

            //sm.AddLast(0, 0); // make irregular
            for (int i = 2; i < count; i++)
            {
                sm.AddLast(i, i);
            }

            for (int r = 0; r < 10; r++)
            {
                var map =
                    new ArithmeticSeries <int, double, MultiplyOp <double>, SortedMapCursor <int, double> >(
                        sm.GetEnumerator(), 2.0);
                var map2 =
                    new ArithmeticSeries <int, double, MultiplyOp <double>, ArithmeticSeries <int, double,
                                                                                              MultiplyOp <double>, SortedMapCursor <int, double> > >(
                        map, 2.0);
                var sum = 0.0;
                using (Benchmark.Run("ArithmeticSeries", count))
                {
                    foreach (var kvp in map2)
                    {
                        sum += kvp.Value;
                    }
                }
                Assert.IsTrue(sum > 0);
            }

            for (int r = 0; r < 10; r++)
            {
                var map = sm
                          //.Select(x => new KeyValuePair<int, double>(x.Key, x.Value * 2))
                          .Select(x => new KeyValuePair <int, double>(x.Key, x.Value * 2));
                var sum = 0.0;
                using (Benchmark.Run("LINQ", count))
                {
                    foreach (var kvp in map)
                    {
                        sum += kvp.Value;
                    }
                }
                Assert.IsTrue(sum > 0);
            }
        }
예제 #6
0
        public void CouldUseRangeCursorStruct()
        {
            SortedMap <int, double> sm = null;

            Assert.Throws <NullReferenceException>(() =>
            {
                var nullRange = new Range <int, double, SortedMapCursor <int, double> >(sm.GetEnumerator(), 0, Int32.MaxValue, true, true);
            });

            var empty = new SortedMap <int, double>();

            var rangeCursor = new Range <int, double, SortedMapCursor <int, double> >(empty.GetEnumerator(), 0, Int32.MaxValue, true, true);
            // NB Source just wraps the cursor in a new struct,
            // same as new CursorSeries<int, double, RangeCursor<int, double, SortedMapCursor<int, double>>>(rangeCursor);
            var range = rangeCursor.Source;

            Assert.True(range.IsEmpty);
            Assert.False(range.Any());

            var nonEmpty = new SortedMap <int, double>
            {
                { 1, 1 }
            };
            var rangeCursor1 = new Range <int, double, SortedMapCursor <int, double> >(nonEmpty.GetEnumerator(), 0, Int32.MaxValue, true, true);
            var range1       = rangeCursor1.Source;

            Assert.True(range1.Any());
        }
예제 #7
0
        public void CouldCalculateSMAWithCount()
        {
            var count = 20;
            var sm    = new SortedMap <int, double>();

            for (int i = 1; i <= count; i++)
            {
                sm.Add(i, i);
            }

            DoTest(true);
            DoTest(false);

            DoTestViaSpanOpCount(true);
            DoTestViaSpanOpCount(false);

            void DoTest(bool allowIncomplete)
            {
                // TODO separate tests/cases for true/false
                var smaOp     = new MAvgCount <int, double, SortedMapCursor <int, double> >(10, allowIncomplete);
                var smaCursor =
                    new SpanOpImpl <int,
                                    double,
                                    double,
                                    MAvgCount <int, double, SortedMapCursor <int, double> >,
                                    SortedMapCursor <int, double>
                                    >(sm.GetEnumerator(), smaOp);

                // this monster type must be hidden in the same way Lag hides its implementation
                Series <int, double, SpanOpImpl <int, double, double, MAvgCount <int, double, SortedMapCursor <int, double> >, SortedMapCursor <int, double> > > smaSeries;

                smaSeries = smaCursor.Source;

                var sm2 = smaSeries.ToSortedMap();

                Assert.AreEqual(sm2.First, smaSeries.First);
                Assert.AreEqual(sm2.Last, smaSeries.Last);

                Assert.True(SeriesContract.MoveAtShouldWorkOnLazySeries(smaSeries));
                Assert.True(SeriesContract.ClonedCursorsAreIndependent(smaSeries));

                if (!allowIncomplete)
                {
                    var trueSma = sm.Window(10).Map(x => x.Values.Average());
                    Assert.True(trueSma.Keys.SequenceEqual(smaSeries.Keys));
                    Assert.True(trueSma.Values.SequenceEqual(smaSeries.Values));
                }

                Debug.WriteLine("SMA");
                foreach (var keyValuePair in smaSeries)
                {
                    Debug.WriteLine($"{keyValuePair.Key} - {keyValuePair.Value}");
                }
            }

            void DoTestViaSpanOpCount(bool allowIncomplete)
            {
                // TODO separate tests/cases for true/false
                var onlineOp  = new SumAvgOnlineOp <int, double, SortedMapCursor <int, double> >();
                var smaOp     = new SpanOpCount <int, double, double, SortedMapCursor <int, double>, SumAvgOnlineOp <int, double, SortedMapCursor <int, double> > >(10, allowIncomplete, onlineOp);
                var smaCursor =
                    new SpanOpImpl <int,
                                    double,
                                    double,
                                    SpanOpCount <int, double, double, SortedMapCursor <int, double>, SumAvgOnlineOp <int, double, SortedMapCursor <int, double> > >,
                                    SortedMapCursor <int, double>
                                    >(sm.GetEnumerator(), smaOp);

                // this monster type must be hidden in the same way Lag hides its implementation
                Series <int, double, SpanOpImpl <int, double, double, SpanOpCount <int, double, double, SortedMapCursor <int, double>, SumAvgOnlineOp <int, double, SortedMapCursor <int, double> > >, SortedMapCursor <int, double> > > smaSeries;

                smaSeries = smaCursor.Source;

                var sm2 = smaSeries.ToSortedMap();

                Assert.AreEqual(sm2.First, smaSeries.First);
                Assert.AreEqual(sm2.Last, smaSeries.Last);

                Assert.True(SeriesContract.MoveAtShouldWorkOnLazySeries(smaSeries));
                Assert.True(SeriesContract.ClonedCursorsAreIndependent(smaSeries));

                if (!allowIncomplete)
                {
                    var trueSma = sm.Window(10).Map(x => x.Values.Average());
                    Assert.True(trueSma.Keys.SequenceEqual(smaSeries.Keys));
                    Assert.True(trueSma.Values.SequenceEqual(smaSeries.Values));
                }

                Debug.WriteLine("SMA");
                foreach (var keyValuePair in smaSeries)
                {
                    Debug.WriteLine($"{keyValuePair.Key} - {keyValuePair.Value}");
                }
            }
        }
예제 #8
0
        public void CouldUseStructSeries()
        {
            var sm    = new SortedMap <int, double>();
            var count = 10000000;

            sm.AddLast(0, 0); // make irregular
            for (int i = 2; i < count; i++)
            {
                sm.AddLast(i, i);
            }

            for (int r = 0; r < 10; r++)
            {
                var sum = 0.0;
                {
                    using (Benchmark.Run("SortedMap", count))
                    {
                        foreach (var kvp in sm)
                        {
                            sum += kvp.Value;
                        }
                    }
                    Assert.IsTrue(sum > 0);
                }

                sum = 0.0;
                {
                    var map =
                        new ArithmeticSeries <int, double, MultiplyOp <double>, SortedMapCursor <int, double> >(
                            sm.GetEnumerator(), 2.0);
                    var map2 =
                        new ArithmeticSeries <int, double, AddOp <double>, ArithmeticSeries <int, double,
                                                                                             MultiplyOp <double>, SortedMapCursor <int, double> > >(
                            map, 2.0);

                    using (Benchmark.Run("ArithmeticSeries", count))
                    {
                        foreach (var kvp in map2)
                        {
                            sum += kvp.Value;
                        }
                    }
                    Assert.IsTrue(sum > 0);
                }
                var sum1 = 0.0;
                {
                    var c =
                        new Op <int, double, MultiplyOp <double>, SortedMapCursor <int, double> >(
                            sm.GetEnumerator(), 2.0);
                    var c1 =
                        new Op <int, double, AddOp <double>, Op <int, double,
                                                                 MultiplyOp <double>, SortedMapCursor <int, double> > >(
                            c, 2.0);

                    using (Benchmark.Run("ArithmeticCursor", count))
                    {
                        foreach (var kvp in c1.Source)
                        {
                            sum1 += kvp.Value;
                        }
                    }
                    Assert.IsTrue(sum1 > 0);
                }

                Assert.AreEqual(sum, sum1);
            }

            Benchmark.Dump("Compare enumeration speed of SortedMap and two arithmetic implementations using class and struct (item workload is multiply by 2 then add 2).");
        }
예제 #9
0
파일: SCMTests.cs 프로젝트: lulzzz/Spreads
        public void EnumerateScmSpeed()
        {
            const int count = 10_000_000;

            var sl = new SortedList <int, int>();
            var sm = new SortedMap <int, int>();

            sm.IsSynchronized = false;
            var scm = new SortedChunkedMap <int, int>();

            scm.IsSynchronized = false;

            for (int i = 0; i < count; i++)
            {
                if (i % 1000 != 0)
                {
                    sl.Add(i, i);
                    sm.Add(i, i);
                    scm.Add(i, i);
                }
            }

            //var ism = new ImmutableSortedMap<int, int>(sm);

            long sum;

            for (int r = 0; r < 20; r++)
            {
                sum = 0L;
                using (Benchmark.Run("SL", count))
                {
                    using (var c = sl.GetEnumerator())
                    {
                        while (c.MoveNext())
                        {
                            sum += c.Current.Value;
                        }
                    }
                }
                Assert.True(sum > 0);

                sum = 0L;
                using (Benchmark.Run("SM", count))
                {
                    using (var c = sm.GetEnumerator())
                    {
                        while (c.MoveNext())
                        {
                            sum += c.Current.Value;
                        }
                    }
                }
                Assert.True(sum > 0);

                //sum = 0L;
                //using (Benchmark.Run("ISM", count))
                //{
                //    foreach (var item in ism)
                //    {
                //        sum += item.Value;
                //    }
                //}
                //Assert.True(sum > 0);

                sum = 0L;
                using (Benchmark.Run("SCM", count))
                {
                    using (var c = scm.GetEnumerator())
                    {
                        while (c.MoveNext())
                        {
                            sum += c.Current.Value;
                        }
                    }
                }
                Assert.True(sum > 0);
            }

            Benchmark.Dump();
        }
예제 #10
0
        public void CouldMapValuesBenchmark()
        {
            var sm    = new SortedMap <int, double>();
            var count = 10000000;

            sm.AddLast(0, 0);
            for (int i = 2; i < count; i++)
            {
                sm.AddLast(i, i);
            }

            for (int r = 0; r < 10; r++)
            {
                var sw = new Stopwatch();
                sw.Restart();
                var map  = new MapValuesSeries <int, double, double, SortedMapCursor <int, double> >(sm.GetEnumerator(), i => i * 2);
                var map2 = new MapValuesSeries <int, double, double, MapValuesSeries <int, double, double, SortedMapCursor <int, double> > >(map, i => i * 2);
                var sum  = 0.0;
                foreach (var kvp in map2)
                {
                    sum += kvp.Value;
                }
                sw.Stop();
                Assert.IsTrue(sum > 0);

                Console.WriteLine($"Mops {sw.MOPS(count)}");
            }

            //for (int r = 0; r < 10; r++)
            //{
            //    var sw = new Stopwatch();
            //    sw.Restart();
            //    var map = sm
            //        //.Select(x => new KeyValuePair<int, double>(x.Key, x.Value * 2))
            //        .Select(x => new KeyValuePair<int, double>(x.Key, x.Value * 2));
            //    var sum = 0.0;
            //    foreach (var kvp in map)
            //    {
            //        sum += kvp.Value;
            //    }
            //    sw.Stop();
            //    Assert.IsTrue(sum > 0);

            //    Console.WriteLine($"LINQ Mops {sw.MOPS(count)}");
            //}
        }
예제 #11
0
        public void CouldMapValues()
        {
            var sm = new SortedMap <int, double>
            {
                { 1, 1 }
            };

            Series <int, double, Range <int, double, SortedMapCursor <int, double> > > s1;

            s1 = sm.After(1);
            // TODO see the monster signature!
            // try to swap Map with Range (or any CursorSeries) so that this signature could
            // be automatically reduced to just two step
            var m2 = s1.Map((x) => x + 1).After(1)
                     .Map((x) => x + 1).After(1).Map((x) => x + 1).After(1).Map((x) => x + 1)
                     .Map((x) => x + 1).After(1).Map((x) => x + 1).After(1).Map((x) => x + 1)
                     .Map((x) => x + 1).After(1).Map((x) => x + 1).After(1).Map((x) => x + 1)
                     .Map((x) => x + 1).After(1).Map((x) => x + 1).After(1).Map((x) => x + 1)
                     .Map((x) => x + 1).After(1).Map((x) => x + 1).After(1).Map((x) => x + 1)
                     .Map((x) => x + 1).After(1).Map((x) => x + 1).After(1).Map((x) => x + 1)
                     .Map((x) => x + 1).After(1).Map((x) => x + 1).After(1).Map((x) => x + 1);

            var map  = new MapValuesSeries <int, double, double, SortedMapCursor <int, double> >(sm.GetEnumerator(), i => i * 2);
            var map1 = new MapValuesSeries <int, double, double, MapValuesSeries <int, double, double, SortedMapCursor <int, double> > >(map, i => i * 2);
            var map2 = new MapValuesSeries <int, double, double, Cursor <int, double> >(new Cursor <int, double>(map.Range(0, Int32.MaxValue, true, true).GetEnumerator()), i => i * 2);
            var map3 = new MapValuesSeries <int, double, double, Cursor <int, double> >(new Cursor <int, double>(map.Range(2, Int32.MaxValue, true, true).GetEnumerator()), i => i * 2);

            Assert.AreEqual(2, map.First.Value);
            Assert.AreEqual(4, map1.First.Value);
            Assert.AreEqual(4, map2.First.Value);
            Assert.True(map3.IsEmpty);
        }
예제 #12
0
        public void Stat2StDevBenchmark()
        {
            var comparer = KeyComparer <int> .Default;
            var count    = 1_000_000;
            var width    = 20;
            var sm       = new SortedMap <int, double>(count, comparer);

            sm.Add(0, 0);
            for (int i = 2; i <= count; i++)
            {
                sm.Add(i, i);
            }

            // var ds1 = new Deedle.Series<int, double>(sm.Keys.ToArray(), sm.Values.ToArray());

            var sum = 0.0;

            for (int r = 0; r < 10; r++)
            {
                var sum1 = 0.0;
                using (Benchmark.Run("Stat2 Online N", count * width))
                {
                    foreach (var stat2 in sm.Stat2(width).Values)
                    {
                        sum1 += stat2.StDev;
                    }
                }
                Assert.True(sum1 != 0);

                var sum2 = 0.0;
                using (Benchmark.Run("Stat2 Online Width GE", count * width))
                {
                    foreach (var stat2 in sm.Stat2(width - 1, Lookup.GE).Values)
                    {
                        sum2 += stat2.StDev;
                    }
                }
                Assert.True(sum2 != 0);

                var sum3 = 0.0;
                using (Benchmark.Run("Stat2 Window N", count * width))
                {
                    foreach (var stat2 in sm.Window(width).Map(x => x.Stat2()).Values)
                    {
                        sum3 += stat2.StDev;
                    }
                }
                Assert.True(sum3 != 0);

                var sum4 = 0.0;
                using (Benchmark.Run("Stat2 Window Width GE", count * width))
                {
                    foreach (var stat2 in sm.Window(width - 1, Lookup.GE).Map(x => x.Stat2()).Values)
                    {
                        sum4 += stat2.StDev;
                    }
                }
                Assert.True(sum4 != 0);

                //var sum5 = 0.0;
                //using (Benchmark.Run("Deedle (online)", count * width))
                //{
                //    var deedleStDev = Deedle.Stats.movingStdDev(width, ds1);
                //    foreach (var keyValuePair in deedleStDev.Values)
                //    {
                //        sum5 += keyValuePair;
                //    }
                //}
                //Assert.True(sum5 != 0);

                Assert.True(Math.Abs(sum1 / sum2 - 1) < 0.000001);
                Assert.True(Math.Abs(sum1 / sum3 - 1) < 0.000001);
                Assert.True(Math.Abs(sum1 / sum4 - 1) < 0.000001);
                // Assert.True(Math.Abs(sum1 / sum5 - 1) < 0.000001);

                sum = 0.0;
                using (Benchmark.Run("SortedMap enumeration", count))
                {
                    var cursor = sm.GetEnumerator();
                    while (cursor.MoveNext())
                    {
                        sum += cursor.CurrentValue;
                    }
                }
                Assert.True(sum != 0);
            }

            Benchmark.Dump($"The window width is {width}. Stat2 MOPS are calculated as a number of calculated values multiplied by width, " +
                           $"which is equivalent to the total number of cursor moves for Window case. SortedMap line is for reference - it is the " +
                           $"speed of raw iteration over SM without Stat2/Windows overheads (and not multiplied by width).");
        }
예제 #13
0
        public void WindowDirectAndIndirectSpanOpBenchmark()
        {
            Settings.DoAdditionalCorrectnessChecks = false;

            var count = 100000;
            var width = 20;
            var sm    = new SortedMap <int, double>();

            sm.Add(0, 0); // make irregular, it's faster but more memory
            for (int i = 2; i <= count; i++)
            {
                sm.Add(i, i);
            }

            var op     = new WindowOnlineOp <int, double, SortedMapCursor <int, double> >();
            var spanOp =
                new SpanOpCount <int, double, Range <int, double, SortedMapCursor <int, double> >,
                                 SortedMapCursor <int, double>, WindowOnlineOp <int, double, SortedMapCursor <int, double> > >(20, false,
                                                                                                                               op);
            var window =
                new SpanOpImpl <int,
                                double,
                                Range <int, double, SortedMapCursor <int, double> >,
                                SpanOpCount <int, double, Range <int, double, SortedMapCursor <int, double> >, SortedMapCursor <int, double>, WindowOnlineOp <int, double, SortedMapCursor <int, double> > >,
                                SortedMapCursor <int, double>
                                >(sm.GetEnumerator(), spanOp).Source
                .Map(x =>
            {
                var sum = 0.0;
                var c   = 0;
                foreach (var keyValuePair in x.Source)
                {
                    sum += keyValuePair.Value;
                    c++;
                }
                return(sum / c);        // x.CursorDefinition.Count TODO
            });

            var spanOpCombined =
                new SpanOp <int, double, Range <int, double, SortedMapCursor <int, double> >,
                            SortedMapCursor <int, double>, WindowOnlineOp <int, double, SortedMapCursor <int, double> > >(20, false,
                                                                                                                          op, sm.comparer);
            var windowCombined =
                new SpanOpImpl <int,
                                double,
                                Range <int, double, SortedMapCursor <int, double> >,
                                SpanOp <int, double, Range <int, double, SortedMapCursor <int, double> >, SortedMapCursor <int, double>, WindowOnlineOp <int, double, SortedMapCursor <int, double> > >,
                                SortedMapCursor <int, double>
                                >(sm.GetEnumerator(), spanOpCombined).Source
                .Map(x =>
            {
                var sum = 0.0;
                var c   = 0;
                foreach (var keyValuePair in x.Source)
                {
                    sum += keyValuePair.Value;
                    c++;
                }
                return(sum / c);    // x.CursorDefinition.Count TODO
            });

            var windowExtension = sm.Window(width).Map(x =>
            {
                var sum = 0.0;
                var c   = 0;
                foreach (var keyValuePair in x)
                {
                    sum += keyValuePair.Value;
                    c++;
                }
                return(sum / c); // x.CursorDefinition.Count TODO
            });

            for (int round = 0; round < 20; round++)
            {
                double sum1 = 0.0;
                using (Benchmark.Run("Window SpanOpCount", count * width))
                {
                    foreach (var keyValuePair in window)
                    {
                        sum1 += keyValuePair.Value;
                    }
                }

                double sum2 = 0.0;
                using (Benchmark.Run("Window SpanOp", count * width))
                {
                    foreach (var keyValuePair in windowCombined)
                    {
                        sum2 += keyValuePair.Value;
                    }
                }

                double sum3 = 0.0;
                using (Benchmark.Run("Window Extension", count * width))
                {
                    foreach (var keyValuePair in windowExtension)
                    {
                        sum3 += keyValuePair.Value;
                    }
                }

                Assert.AreEqual(sum1, sum2);
                Assert.AreEqual(sum1, sum3);
            }

            Benchmark.Dump($"The window width is {width}.");
        }
예제 #14
0
        public void CouldCalculateSMAWithWidth()
        {
            var count = 20;
            var sm    = new SortedMap <int, double>();

            for (int i = 1; i <= count; i++)
            {
                sm.Add(i, i);
            }

            DoTest(Lookup.EQ);
            DoTest(Lookup.GE);
            DoTest(Lookup.GT);
            DoTest(Lookup.LE);
            DoTest(Lookup.LT);

            DoTestViaSpanOpWidth(Lookup.EQ);
            DoTestViaSpanOpWidth(Lookup.GE);
            DoTestViaSpanOpWidth(Lookup.GT);
            DoTestViaSpanOpWidth(Lookup.LE);
            DoTestViaSpanOpWidth(Lookup.LT);

            void DoTest(Lookup lookup)
            {
                // width 9 is the same as count = 10 for the regular int series
                var smaOp     = new MAvgWidth <int, double, SortedMapCursor <int, double> >(9, lookup);
                var smaCursor =
                    new SpanOpImpl <int,
                                    double,
                                    double,
                                    MAvgWidth <int, double, SortedMapCursor <int, double> >,
                                    SortedMapCursor <int, double>
                                    >(sm.GetEnumerator(), smaOp);

                // this monster type must be hidden in the same way Lag hides its implementation
                Series <int, double, SpanOpImpl <int, double, double, MAvgWidth <int, double, SortedMapCursor <int, double> >, SortedMapCursor <int, double> > > smaSeries;

                smaSeries = smaCursor.Source;

                var sm2 = smaSeries.ToSortedMap();

                Assert.AreEqual(sm2.First, smaSeries.First);
                Assert.AreEqual(sm2.Last, smaSeries.Last);

                Assert.True(SeriesContract.MoveAtShouldWorkOnLazySeries(smaSeries));
                Assert.True(SeriesContract.ClonedCursorsAreIndependent(smaSeries));

                if (lookup == Lookup.EQ || lookup == Lookup.GE)
                {
                    var trueSma = sm.Window(10).Map(x => x.Values.Average());
                    Assert.True(trueSma.Keys.SequenceEqual(smaSeries.Keys));
                    Assert.True(trueSma.Values.SequenceEqual(smaSeries.Values));
                }

                if (lookup == Lookup.GT)
                {
                    var trueSma = sm.Window(11).Map(x => x.Values.Average());
                    Assert.True(trueSma.Keys.SequenceEqual(smaSeries.Keys));
                    Assert.True(trueSma.Values.SequenceEqual(smaSeries.Values));
                }

                if (lookup == Lookup.LE)
                {
                    var smaOp1  = new MAvgCount <int, double, SortedMapCursor <int, double> >(10, true);
                    var trueSma =
                        new SpanOpImpl <int,
                                        double,
                                        double,
                                        MAvgCount <int, double, SortedMapCursor <int, double> >,
                                        SortedMapCursor <int, double>
                                        >(sm.GetEnumerator(), smaOp1).Source;

                    Assert.True(trueSma.Keys.SequenceEqual(smaSeries.Keys));
                    Assert.True(trueSma.Values.SequenceEqual(smaSeries.Values));
                }

                if (lookup == Lookup.LT)
                {
                    var smaOp1  = new MAvgCount <int, double, SortedMapCursor <int, double> >(9, true);
                    var trueSma =
                        new SpanOpImpl <int,
                                        double,
                                        double,
                                        MAvgCount <int, double, SortedMapCursor <int, double> >,
                                        SortedMapCursor <int, double>
                                        >(sm.GetEnumerator(), smaOp1).Source;

                    Assert.True(trueSma.Keys.SequenceEqual(smaSeries.Keys));
                    Assert.True(trueSma.Values.SequenceEqual(smaSeries.Values));
                }

                Debug.WriteLine("SMA");
                foreach (var keyValuePair in smaSeries)
                {
                    Debug.WriteLine($"{keyValuePair.Key} - {keyValuePair.Value}");
                }
            }

            void DoTestViaSpanOpWidth(Lookup lookup)
            {
                // width 9 is the same as count = 10 for the regular int series

                var onlineOp  = new SumAvgOnlineOp <int, double, SortedMapCursor <int, double> >();
                var smaOp     = new SpanOpWidth <int, double, double, SortedMapCursor <int, double>, SumAvgOnlineOp <int, double, SortedMapCursor <int, double> > >(9, lookup, onlineOp);
                var smaCursor =
                    new SpanOpImpl <int,
                                    double,
                                    double,
                                    SpanOpWidth <int, double, double, SortedMapCursor <int, double>, SumAvgOnlineOp <int, double, SortedMapCursor <int, double> > >,
                                    SortedMapCursor <int, double>
                                    >(sm.GetEnumerator(), smaOp);

                // this monster type must be hidden in the same way Lag hides its implementation

                Series <int, double, SpanOpImpl <int, double, double, SpanOpWidth <int, double, double, SortedMapCursor <int, double>, SumAvgOnlineOp <int, double, SortedMapCursor <int, double> > >, SortedMapCursor <int, double> > > smaSeries;

                smaSeries = smaCursor.Source;

                var sm2 = smaSeries.ToSortedMap();

                Assert.AreEqual(sm2.First, smaSeries.First);
                Assert.AreEqual(sm2.Last, smaSeries.Last);

                Assert.True(SeriesContract.MoveAtShouldWorkOnLazySeries(smaSeries));
                Assert.True(SeriesContract.ClonedCursorsAreIndependent(smaSeries));

                if (lookup == Lookup.EQ || lookup == Lookup.GE)
                {
                    var trueSma = sm.Window(10).Map(x => x.Values.Average());
                    Assert.True(trueSma.Keys.SequenceEqual(smaSeries.Keys));
                    Assert.True(trueSma.Values.SequenceEqual(smaSeries.Values));
                }

                if (lookup == Lookup.GT)
                {
                    var trueSma = sm.Window(11).Map(x => x.Values.Average());
                    Assert.True(trueSma.Keys.SequenceEqual(smaSeries.Keys));
                    Assert.True(trueSma.Values.SequenceEqual(smaSeries.Values));
                }

                if (lookup == Lookup.LE)
                {
                    var smaOp1  = new MAvgCount <int, double, SortedMapCursor <int, double> >(10, true);
                    var trueSma =
                        new SpanOpImpl <int,
                                        double,
                                        double,
                                        MAvgCount <int, double, SortedMapCursor <int, double> >,
                                        SortedMapCursor <int, double>
                                        >(sm.GetEnumerator(), smaOp1).Source;

                    Assert.True(trueSma.Keys.SequenceEqual(smaSeries.Keys));
                    Assert.True(trueSma.Values.SequenceEqual(smaSeries.Values));
                }

                if (lookup == Lookup.LT)
                {
                    var smaOp1  = new MAvgCount <int, double, SortedMapCursor <int, double> >(9, true);
                    var trueSma =
                        new SpanOpImpl <int,
                                        double,
                                        double,
                                        MAvgCount <int, double, SortedMapCursor <int, double> >,
                                        SortedMapCursor <int, double>
                                        >(sm.GetEnumerator(), smaOp1).Source;

                    Assert.True(trueSma.Keys.SequenceEqual(smaSeries.Keys));
                    Assert.True(trueSma.Values.SequenceEqual(smaSeries.Values));
                }

                Debug.WriteLine("SMA");
                foreach (var keyValuePair in smaSeries)
                {
                    Debug.WriteLine($"{keyValuePair.Key} - {keyValuePair.Value}");
                }
            }
        }
예제 #15
0
        public void CouldMoveAt()
        {
            var count = 100;
            var sm0   = new SortedMap <int, double>();
            var sm1   = new SortedMap <int, double>();
            var sm2   = new SortedMap <int, double>();

            double expected = 0;

            for (int i = 1; i < count; i++)
            {
                sm0.Add(i, i);

                if (i % 3 == 0)
                {
                    sm2.Add(i, 2 * i);
                    expected += 123 + 2 * i;
                }
                else
                {
                    sm1.Add(i, i);
                    expected += i + 42;
                }
            }

            var fc  = new Fill <int, double, SortedMapCursor <int, double> >(sm0.GetEnumerator(), -1);
            var fc1 = new Fill <int, double, SortedMapCursor <int, double> >(sm1.GetEnumerator(), 123);
            var fc2 = new Fill <int, double, SortedMapCursor <int, double> >(sm2.GetEnumerator(), 42);

            var zipCursor =
                new Zip <int, double, double, Fill <int, double, SortedMapCursor <int, double> >,
                         Fill <int, double, SortedMapCursor <int, double> > >(
                    fc, fc2).Map((k, v) => v.Item1 + v.Item2)
                .Initialize();

            Assert.IsTrue(zipCursor.MoveAt(2, Lookup.EQ));
            Assert.AreEqual(44, zipCursor.CurrentValue);

            Assert.IsTrue(zipCursor.MoveAt(2, Lookup.LE));
            Assert.AreEqual(44, zipCursor.CurrentValue);

            Assert.IsTrue(zipCursor.MoveAt(2, Lookup.GE));
            Assert.AreEqual(44, zipCursor.CurrentValue);

            Assert.IsTrue(zipCursor.MoveAt(2, Lookup.LT));
            Assert.AreEqual(43, zipCursor.CurrentValue);

            Assert.IsTrue(zipCursor.MoveAt(2, Lookup.GT));
            Assert.AreEqual(9, zipCursor.CurrentValue);

            var zipCursor1 =
                new Zip <int, double, double, Fill <int, double, SortedMapCursor <int, double> >,
                         Fill <int, double, SortedMapCursor <int, double> > >(
                    fc1, fc2).Map((k, v) => v.Item1 + v.Item2)
                .Initialize();

            Assert.IsTrue(zipCursor1.MoveAt(2, Lookup.EQ));
            Assert.AreEqual(44, zipCursor1.CurrentValue);

            Assert.IsTrue(zipCursor1.MoveAt(2, Lookup.LE));
            Assert.AreEqual(44, zipCursor1.CurrentValue);

            Assert.IsTrue(zipCursor1.MoveAt(2, Lookup.GE));
            Assert.AreEqual(44, zipCursor1.CurrentValue);

            Assert.IsTrue(zipCursor1.MoveAt(2, Lookup.LT));
            Assert.AreEqual(43, zipCursor1.CurrentValue);

            Assert.IsTrue(zipCursor1.MoveAt(2, Lookup.GT));
            Assert.AreEqual(129, zipCursor1.CurrentValue);
        }
예제 #16
0
        public void CouldAddContinuousSeries()
        {
            var count = 10000; //0;
            var sm1   = new SortedMap <int, double>();
            var sm2   = new SortedMap <int, double>();

            double expected = 0;

            for (int i = 1; i < count; i++)
            {
                if (i % 2 == 0)
                {
                    sm2.Add(i, 2 * i);
                    expected += 123 + 2 * i;
                }
                else
                {
                    sm1.Add(i, i);
                    expected += i + 42;
                }
            }

            for (int r = 0; r < 20; r++)
            {
                var fc1       = new Fill <int, double, SortedMapCursor <int, double> >(sm1.GetEnumerator(), 123);
                var fc2       = new Fill <int, double, SortedMapCursor <int, double> >(sm2.GetEnumerator(), 42);
                var zipCursor =
                    new Zip <int, double, double, Fill <int, double, SortedMapCursor <int, double> >,
                             Fill <int, double, SortedMapCursor <int, double> > >(
                        fc1, fc2).Map((k, v) => v.Item1 + v.Item2)
                    .Initialize();

                double actual = 0;
                using (Benchmark.Run("ZipContinuous MN", (sm1.Count + sm2.Count) * 2)
                       ) // NB multiply by 2, we evaluate on missing, should count virtual values as well
                {
                    while (zipCursor.MoveNext())
                    {
                        actual += zipCursor.CurrentValue;
                    }
                }
                Assert.AreEqual(expected, actual);

                zipCursor.Reset();
                actual = 0;
                using (Benchmark.Run("ZipContinuous MP", (sm1.Count + sm2.Count) * 2)
                       ) // NB multiply by 2, we evaluate on missing, should count virtual values as well
                {
                    while (zipCursor.MoveNext())
                    {
                        actual += zipCursor.CurrentValue;
                    }
                }
                Assert.AreEqual(expected, actual);
            }

            Benchmark.Dump();
        }
예제 #17
0
        public void CouldAddTwoSeriesWithSameKeys(double expected, SortedMap <int, double> sm1,
                                                  SortedMap <int, double> sm2)
        {
            var count = sm1.Count;

            var c1 = sm1.GetEnumerator();
            var c2 = sm2.GetEnumerator();

            //var ds1 = new Deedle.Series<int, double>(sm1.Keys.ToArray(), sm1.Values.ToArray());
            //var ds2 = new Deedle.Series<int, double>(sm2.Keys.ToArray(), sm2.Values.ToArray());

            Assert.NotNull(c1.Comparer);
            Assert.NotNull(c2.Comparer);

            var    zipSum    = (sm1 + sm2);
            double actual    = 0;
            var    zipCursor = //zipSum.GetAsyncEnumerator();
                               new Zip <int, double, double, SortedMapCursor <int, double>,
                                        SortedMapCursor <int, double> >(
                c1, c2);         //.Map((k, v) => v.Item1 + v.Item2)

            var op2 = new Op2 <int, double, AddOp <double>, Zip <int, double, double, SortedMapCursor <int, double>,
                                                                 SortedMapCursor <int, double> > >(zipCursor).Source;

            var zipCursorOp2 = op2.GetEnumerator();

            using (Benchmark.Run("Zip", count * 2))
            {
                while (zipCursorOp2.MoveNext())
                {
                    actual += zipCursorOp2.CurrentValue;
                }
            }
            Assert.AreEqual(expected, actual);

            //var zipped = sm1.Zip(sm2, (k, l, r) => l + r); // sm1.Zip(sm2).Map((k, v) => v.Item1 + v.Item2); //
            //actual = 0;
            //using (Benchmark.Run("Zip MN Extension", count * 2))
            //{
            //    foreach (var keyValuePair in zipped)
            //    {
            //        actual += keyValuePair.Value;
            //    }
            //}
            //Assert.AreEqual(expected, actual);

            //var zipN = new[] { sm1, sm2 }.Zip((k, varr) => varr[0] + varr[1], true).GetCursor();
            //actual = 0;
            //using (Benchmark.Run("ZipN", count * 2))
            //{
            //    while (zipN.MoveNextAsync())
            //    {
            //        actual += zipN.CurrentValue;
            //    }
            //}
            //Assert.AreEqual(expected, actual);

            //var zipNOld = new[] { sm1, sm2 }.ZipOld((k, varr) => varr[0] + varr[1]).GetCursor();
            //actual = 0;
            //using (Benchmark.Run("ZipN (old)", count * 2))
            //{
            //    while (zipNOld.MoveNextAsync())
            //    {
            //        actual += zipNOld.CurrentValue;
            //    }
            //}
            //Assert.AreEqual(expected, actual);

            //zipCursor.Reset();
            //actual = 0;
            //using (Benchmark.Run("Zip MP", count * 2))
            //{
            //    while (zipCursor.MovePrevious())
            //    {
            //        actual += zipCursor.CurrentValue;
            //    }
            //}
            //Assert.AreEqual(expected, actual);

            //actual = 0;
            //using (Benchmark.Run("LINQ", count * 2))
            //{
            //    var linq = sm1.Zip(sm2, (l, r) => l.Value + r.Value);
            //    foreach (var d in linq)
            //    {
            //        actual += d;
            //    }
            //}
            //Assert.AreEqual(expected, actual);

            //actual = 0;
            //using (Benchmark.Run("Deedle", count * 2))
            //{
            //    var sum = ds1 + ds2;
            //    foreach (var v in sum.Values) // ds1.ZipInner(ds2).Values)
            //    {
            //        actual += v; //.Item1 + v.Item2;
            //    }
            //}
            //Assert.AreEqual(expected, actual);
        }
예제 #18
0
        public void CouldMapValuesBenchmarkArithmeticVsMapCursor()
        {
            var sm    = new SortedMap <int, double>();
            var count = 10000000;

            sm.AddLast(0, 0);
            for (int i = 2; i < count; i++)
            {
                sm.AddLast(i, i);
            }

            for (int r = 0; r < 10; r++)
            {
                {
                    var sum = 0.0;
                    using (Benchmark.Run("SortedMap", count))
                    {
                        foreach (var kvp in sm)
                        {
                            sum += kvp.Value;
                        }
                    }
                    Assert.IsTrue(sum > 0);
                }

                {
                    var map =
                        new ArithmeticSeries <int, double, MultiplyOp <double>, SortedMapCursor <int, double> >(sm.GetEnumerator(),
                                                                                                                2.0);
                    var map2 = map + 2;
                    //new ArithmeticSeries<int, double, MultiplyOp<double>, ArithmeticSeries<int, double,
                    //    MultiplyOp<double>, SortedMapCursor<int, double>>>(
                    //    map.Initialize, 2.0);
                    var sum = 0.0;
                    using (Benchmark.Run("ArithmeticSeries", count))
                    {
                        foreach (var kvp in map2)
                        {
                            sum += kvp.Value;
                        }
                    }
                    Assert.IsTrue(sum > 0);
                }

                {
                    var c =
                        new Op <int, double, MultiplyOp <double>, SortedMapCursor <int, double> >(
                            sm.GetEnumerator(), 2.0);
                    var c1 =
                        new Op <int, double, AddOp <double>, Op <int, double,
                                                                 MultiplyOp <double>, SortedMapCursor <int, double> > >(
                            c, 2.0);
                    var series = new Series <int, double, Op <int, double, AddOp <double>, Op <int, double,
                                                                                               MultiplyOp <double>, SortedMapCursor <int, double> > > >(c1);
                    var sum = 0.0;
                    using (Benchmark.Run("ArithmeticCursor", count))
                    {
                        foreach (var kvp in series)
                        {
                            sum += kvp.Value;
                        }
                    }
                    Assert.IsTrue(sum > 0);
                }

                {
                    var map =
                        new MapValuesSeries <int, double, double, SortedMapCursor <int, double> >(sm.GetEnumerator(),
                                                                                                  i => Apply(i, 2.0));
                    var map2 =
                        new
                        MapValuesSeries <int, double, double, MapValuesSeries <int, double, double,
                                                                               SortedMapCursor <int, double> > >(map, i => Apply2(i, 2.0));
                    var sum = 0.0;
                    using (Benchmark.Run("MapValuesSeries", count))
                    {
                        foreach (var kvp in map2)
                        {
                            sum += kvp.Value;
                        }
                    }
                    Assert.IsTrue(sum > 0);
                }

                {
                    var map = (sm * 2) + 2;
                    var sum = 0.0;
                    using (Benchmark.Run("BaseSeries operator", count))
                    {
                        foreach (var kvp in map)
                        {
                            sum += kvp.Value;
                        }
                    }
                    Assert.IsTrue(sum > 0);
                }

                {
                    var map = sm
                              .Select(x => new KeyValuePair <int, double>(x.Key, x.Value * 2))
                              .Select(x => new KeyValuePair <int, double>(x.Key, x.Value + 2));
                    var sum = 0.0;
                    using (Benchmark.Run("LINQ", count))
                    {
                        foreach (var kvp in map)
                        {
                            sum += kvp.Value;
                        }
                    }
                    Assert.IsTrue(sum > 0);
                }
            }

            Benchmark.Dump();
        }
예제 #19
0
        // TODO learn how to use dotMemory for total allocatoins count
        //[DotMemoryUnit(FailIfRunWithoutSupport = false)]
        public void MultipleEnumerationDoesntAllocate()
        {
            var sm    = new SortedMap <int, double>();
            var count = 100;

            sm.AddLast(0, 0);
            for (int i = 2; i < count; i++)
            {
                sm.AddLast(i, i);
            }

            for (int r = 0; r < 10; r++)
            {
                var map =
                    new ArithmeticSeries <int, double, MultiplyOp <double>, SortedMapCursor <int, double> >(
                        sm.GetEnumerator(), 2.0);

                var sum        = 0.0;
                var sum1       = 0.0;
                var sum2       = 0.0;
                var iterations = 100000;

                void Run(ref double s)
                {
                    try
                    {
                        // using it here completely eliminates allocations, an instance is created for
                        // all iterations inside each thread
                        //using (var mapX = map + 2)
                        {
                            for (int i = 0; i < iterations; i++)
                            {
                                // here static caching helps, but not completely eliminates allocations because
                                // two threads compete for a single static slot very often
                                using (var mapX = map + 2)
                                    using (var c = (mapX).GetEnumerator())
                                    {
                                        //Assert.IsTrue(c.State == CursorState.Initialized);
                                        //Assert.IsTrue(c._cursor.State == CursorState.Initialized);

                                        var countCheck = 0;
                                        while (c.MoveNext())
                                        {
                                            s += c.CurrentKey;
                                            countCheck++;
                                        }
                                        if (sm.Count != countCheck)
                                        {
                                            Console.WriteLine($"Expected {sm.Count} vs actual {countCheck}");
                                        }
                                        if (sm.Count != countCheck)
                                        {
                                            Assert.Fail();
                                        }
                                    }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message + Environment.NewLine + ex);
                    }
                }

                var cc =
                    new Op <int, double, MultiplyOp <double>, SortedMapCursor <int, double> >(
                        sm.GetEnumerator(), 2.0);

                var cc1 =
                    new Op <int, double, AddOp <double>, Op <int, double,
                                                             MultiplyOp <double>, SortedMapCursor <int, double> > >(
                        cc, 2.0);
                var series = new Series <int, double, Op <int, double, AddOp <double>, Op <int, double,
                                                                                           MultiplyOp <double>, SortedMapCursor <int, double> > > >(cc1);

                void Run2(ref double s)
                {
                    try
                    {
                        for (int i = 0; i < iterations; i++)
                        {
                            using (var c = series.GetEnumerator())
                            {
                                var countCheck = 0;
                                while (c.MoveNext())
                                {
                                    s += c.CurrentKey;
                                    countCheck++;
                                }
                                if (sm.Count != countCheck)
                                {
                                    Console.WriteLine($"Expected {sm.Count} vs actual {countCheck}");
                                }
                                if (sm.Count != countCheck)
                                {
                                    Assert.Fail();
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message + Environment.NewLine + ex);
                    }
                }

                using (Benchmark.Run("ArithmeticSeries", count * iterations))
                {
                    var t  = Task.Run(() => Run(ref sum1));
                    var t1 = Task.Run(() => Run(ref sum2));
                    Run(ref sum);
                    t.Wait();
                    t1.Wait();

                    //dotMemory.Check(memory =>
                    //{
                    //    Assert.That(
                    //        memory.GetObjects(where =>
                    //            where.Type.Is<ArithmeticSeries<int, double, MultiplyOp<double>, SortedMapCursor<int, double>>>()).ObjectsCount,
                    //        Is.EqualTo(1)
                    //    );
                    //});
                }

                Assert.IsTrue(sum > 0);
                Assert.AreEqual(sum, sum1);
                Assert.AreEqual(sum, sum2);

                using (Benchmark.Run("ArithmeticCursor", count * iterations))
                {
                    var t  = Task.Run(() => Run2(ref sum1));
                    var t1 = Task.Run(() => Run2(ref sum2));
                    Run2(ref sum);
                    t.Wait();
                    t1.Wait();
                }

                Assert.IsTrue(sum > 0);
                Assert.AreEqual(sum, sum1);
                Assert.AreEqual(sum, sum2);
            }
            Benchmark.Dump("Compare multiple allocations and subsequent enumerations of arithmetic series.");
        }
예제 #20
0
        public void SMADirectAndIndirectSpanOpBenchmark()
        {
            Settings.DoAdditionalCorrectnessChecks = false;

            var count = 1000000;
            var width = 20;
            var sm    = new SortedMap <int, double>();

            sm.Add(0, 0); // make irregular, it's faster but more memory
            for (int i = 2; i <= count; i++)
            {
                sm.Add(i, i);
            }

            var directSMA =
                new SpanOpImpl <int,
                                double,
                                double,
                                MAvgCount <int, double, SortedMapCursor <int, double> >,
                                SortedMapCursor <int, double>
                                >(sm.GetEnumerator(), new MAvgCount <int, double, SortedMapCursor <int, double> >(width, false)).Source;

            var indirectSma =
                new SpanOpImpl <int,
                                double,
                                double,
                                SpanOpCount <int, double, double, SortedMapCursor <int, double>, SumAvgOnlineOp <int, double, SortedMapCursor <int, double> > >,
                                SortedMapCursor <int, double>
                                >(sm.GetEnumerator(),
                                  new SpanOpCount <int, double, double, SortedMapCursor <int, double>, SumAvgOnlineOp <int, double, SortedMapCursor <int, double> > >(width, false, new SumAvgOnlineOp <int, double, SortedMapCursor <int, double> >())).Source;

            var indirectSmaCombined =
                new SpanOpImpl <int,
                                double,
                                double,
                                SpanOp <int, double, double, SortedMapCursor <int, double>, SumAvgOnlineOp <int, double, SortedMapCursor <int, double> > >,
                                SortedMapCursor <int, double>
                                >(sm.GetEnumerator(),
                                  new SpanOp <int, double, double, SortedMapCursor <int, double>, SumAvgOnlineOp <int, double, SortedMapCursor <int, double> > >(width, false, new SumAvgOnlineOp <int, double, SortedMapCursor <int, double> >(), sm.comparer)).Source;

            var extensionSma = sm.SMA(width);

            var windowSma = sm.Window(width).Map(x =>
            {
                var sum = 0.0;
                var c   = 0;
                foreach (var keyValuePair in x)
                {
                    sum += keyValuePair.Value;
                    c++;
                }
                return(sum / c); // x.CursorDefinition.Count TODO
            });

            for (int round = 0; round < 20; round++)
            {
                double sum1 = 0.0;
                using (Benchmark.Run("SMA Direct", count * width))
                {
                    foreach (var keyValuePair in directSMA)
                    {
                        sum1 += keyValuePair.Value;
                    }
                }

                double sum2 = 0.0;
                using (Benchmark.Run("SMA Indirect", count * width))
                {
                    foreach (var keyValuePair in indirectSma)
                    {
                        sum2 += keyValuePair.Value;
                    }
                }

                double sum2_2 = 0.0;
                using (Benchmark.Run("SMA Indirect Combined", count * width))
                {
                    foreach (var keyValuePair in indirectSmaCombined)
                    {
                        sum2_2 += keyValuePair.Value;
                    }
                }

                double sum2_3 = 0.0;
                using (Benchmark.Run("SMA Extension", count * width))
                {
                    foreach (var keyValuePair in extensionSma)
                    {
                        sum2_3 += keyValuePair.Value;
                    }
                }

                double sum3 = 0.0;
                using (Benchmark.Run("SMA Window", count * width))
                {
                    foreach (var keyValuePair in windowSma)
                    {
                        sum3 += keyValuePair.Value;
                    }
                }

                var sumxx = 0.0;
                using (Benchmark.Run("SortedMap", count))
                {
                    foreach (var keyValuePair in sm)
                    {
                        sumxx += keyValuePair.Value;
                    }
                }

                Assert.AreEqual(sum1, sum2);
                Assert.AreEqual(sum1, sum2_2);
                Assert.AreEqual(sum1, sum2_3);
                Assert.AreEqual(sum1, sum3);
            }

            Benchmark.Dump($"The window width is {width}. SMA MOPS are calculated as a number of calculated values multiplied by width, " +
                           $"which is equivalent to the total number of cursor moves for Window case. SortedMap line is for reference - it is the " +
                           $"speed of raw iteration over SM without Windows overheads.");
        }
예제 #21
0
        public void CouldUseWindowCursor()
        {
            SortedMap <int, double> sm = new SortedMap <int, double>();

            var count = 100;

            for (int i = 0; i < count; i++)
            {
                sm.Add(i, i);
            }

            var window = sm.Window(10);

            // NB no type annotations needed to get the same result
            // Even though `.Source` saves a great deal of typing, manual construction is still a dealbreaker
            // Extension methods are smart and keep all types info without requiring any type annotations
            var windowLong = new Window <int, double, SortedMapCursor <int, double> >(sm.GetEnumerator(), 10).Source;

            foreach (var pair in window)
            {
                var expected = ((2 * pair.Key - 10 + 1) / 2.0) * 10;
                Assert.AreEqual(expected, pair.Value.Values.Sum());
                Console.WriteLine(pair.Value.Values.Sum());
                //Console.WriteLine(keyValuePair.Value.Aggregate("", (st,kvp) => st + "," + kvp.Value));
            }
        }
예제 #22
0
        public void EnumerateScmSpeed()
        {
            const int count = 10_000_000;

            var sl  = new SortedList <int, int>();
            var sm  = new SortedMap <int, int>();
            var scm = new SortedChunkedMap <int, int>();

            for (int i = 0; i < count; i++)
            {
                if (i % 1000 != 0)
                {
                    sl.Add(i, i);
                    sm.Add(i, i);
                    //scm.Add(i, i);
                }
            }

            sm.Complete();
            // scm.Complete();

            for (int r = 0; r < 20; r++)
            {
                //var sum1 = 0L;
                //using (Benchmark.Run("SL", count))
                //{
                //    using (var c = sl.GetEnumerator())
                //    {
                //        while (c.MoveNext())
                //        {
                //            sum1 += c.Current.Value;
                //        }
                //    }
                //}
                //Assert.True(sum1 > 0);

                var sum2 = 0L;
                using (Benchmark.Run("SM Current.Value", count))
                {
                    using (var c = sm.GetEnumerator())
                    {
                        while (c.MoveNext())
                        {
                            sum2 += c.Current.Value;
                        }
                    }
                }
                //Assert.AreEqual(sum1, sum2);

                var sum3 = 0L;
                using (Benchmark.Run("SM CurrentValue", count))
                {
                    using (var c = sm.GetEnumerator())
                    {
                        while (c.MoveNext())
                        {
                            sum3 += c.CurrentValue;
                        }
                    }
                }
                //Assert.AreEqual(sum1, sum3);

                //var sum4 = 0L;
                //using (Benchmark.Run("SCM Current.Value", count))
                //{
                //    using (var c = scm.GetEnumerator())
                //    {
                //        while (c.MoveNext())
                //        {
                //            sum4 += c.Current.Value;
                //        }
                //    }
                //}
                //Assert.AreEqual(sum1, sum4);

                //var sum5 = 0L;
                //using (Benchmark.Run("SCM CurrentValue", count))
                //{
                //    using (var c = scm.GetEnumerator())
                //    {
                //        while (c.MoveNext())
                //        {
                //            sum5 += c.CurrentValue;
                //        }
                //    }
                //}
                //Assert.AreEqual(sum1, sum5);
            }

            Benchmark.Dump();
        }
예제 #23
0
        public void CouldMapValues()
        {
            var sm = new SortedMap <int, double>
            {
                { 1, 1 }
            };
            var map  = new ArithmeticSeries <int, double, MultiplyOp <double>, SortedMapCursor <int, double> >((sm.GetEnumerator()), 2);
            var map1 = new ArithmeticSeries <int, double, MultiplyOp <double>, ArithmeticSeries <int, double, MultiplyOp <double>,
                                                                                                 SortedMapCursor <int, double> > >(map, 2);

            Assert.AreEqual(2, map.First.Value);
            Assert.AreEqual(4, map1.First.Value);
        }