Exemplo n.º 1
0
        public int Compare(T x, T y)
        {
            if (_comparer != null)
            {
                return(_comparer.Compare(x, y));
            }

            if (typeof(T) == typeof(DateTime))
            {
                var x1 = (DateTime)(object)(x);
                var y1 = (DateTime)(object)(y);

                return(x1.CompareTo(y1));
            }

            if (typeof(T) == typeof(long))
            {
                var x1 = (long)(object)(x);
                var y1 = (long)(object)(y);

                return(x1.CompareTo(y1));
            }

            if (typeof(T) == typeof(ulong))
            {
                var x1 = (ulong)(object)(x);
                var y1 = (ulong)(object)(y);
                return(x1.CompareTo(y1));
            }

            if (typeof(T) == typeof(int))
            {
                var x1 = (int)(object)(x);
                var y1 = (int)(object)(y);
                return(x1.CompareTo(y1));
            }

            if (typeof(T) == typeof(uint))
            {
                var x1 = (uint)(object)(x);
                var y1 = (uint)(object)(y);

                return(x1.CompareTo(y1));
            }

            // NB all primitive types are IComparable, all custom types could be easily made such
            // This optimization using Spreads.Unsafe package works for any type that implements
            // the interface and is as fast as `typeof(T) == typeof(...)` approach.
            // The special cases above are left for scenarios when the "static readonly" optimization
            // doesn't work, e.g. AOT. See discussion #100.
            if (IsIComparable)
            {
                return(Unsafe.CompareToConstrained(ref x, ref y));
            }

            return(CompareSlow(x, y));
        }
Exemplo n.º 2
0
        public void ComparerInterfaceAndCachedConstrainedComparer()
        {
            var c = Comparer <long> .Default;
            IComparer <long> ic = Comparer <long> .Default;
            var cc = KeyComparer <long> .Default;

            const int count = 100000000;

            for (int r = 0; r < 10; r++)
            {
                var sum = 0L;

                using (Benchmark.Run("Default", count))
                {
                    for (int i = 0; i < count; i++)
                    {
                        sum += c.Compare(i, i - 1);
                    }
                }

                Assert.True(sum > 0);

                sum = 0L;
                using (Benchmark.Run("Interface", count))
                {
                    for (int i = 0; i < count; i++)
                    {
                        sum += ic.Compare(i, i - 1);
                    }
                }
                Assert.True(sum > 0);

                sum = 0L;
                using (Benchmark.Run("KeyComparer", count))
                {
                    for (int i = 0; i < count; i++)
                    {
                        sum += cc.Compare(i, i - 1);
                    }
                }
                Assert.True(sum > 0);

                sum = 0L;
                using (Benchmark.Run("Unsafe", count))
                {
                    for (int i = 0; i < count; i++)
                    {
                        var other = i - 1;
                        sum += Unsafe.CompareToConstrained(ref i, ref other);
                    }
                }
            }

            Benchmark.Dump();
        }
Exemplo n.º 3
0
        public void CouldUseCompareAndEqualsMethods()
        {
            var v1 = new CompEq(1);
            var v2 = new CompEq(2);
            var v3 = new CompEq(2);

            Assert.AreEqual(-1, Unsafe.CompareToConstrained(ref v1, ref v2));
            Assert.AreEqual(1, Unsafe.CompareToConstrained(ref v2, ref v1));
            Assert.AreEqual(0, Unsafe.CompareToConstrained(ref v2, ref v3));
            Assert.AreEqual(1, Unsafe.CompareToConstrained(ref v3, ref v1));

            Assert.True(Unsafe.EqualsConstrained(ref v2, ref v3));
            Assert.False(Unsafe.EqualsConstrained(ref v1, ref v3));
        }