Ver Fonte

2005-06-12 Ben Maurer <[email protected]>

	* Comparer.cs, EqualityComparer.cs: Important performance hack:
	make sure that we don't box stuff and do reflection on every
	comparison. We use reflection at cctor time rather than on every
	request.


svn path=/trunk/mcs/; revision=45833
Ben Maurer há 20 anos atrás
pai
commit
05aecab26c

+ 7 - 0
mcs/class/corlib/System.Collections.Generic/ChangeLog

@@ -1,3 +1,10 @@
+2005-06-12  Ben Maurer  <[email protected]>
+
+	* Comparer.cs, EqualityComparer.cs: Important performance hack:
+	make sure that we don't box stuff and do reflection on every
+	comparison. We use reflection at cctor time rather than on every
+	request.
+
 2005-06-09  Raja R Harinath  <[email protected]>
 
 	Simplify Enumerator.MoveNext to make it "obviously correct", rather

+ 26 - 7
mcs/class/corlib/System.Collections.Generic/Comparer.cs

@@ -33,17 +33,23 @@ using System.Runtime.InteropServices;
 namespace System.Collections.Generic {
 	[Serializable]
 	public abstract class Comparer<T> : IComparer<T>, System.Collections.IComparer {
-			
+		
+		static Comparer ()
+		{
+			if (typeof (IComparable<T>).IsAssignableFrom (typeof (T)))
+				_default = (Comparer<T>) Activator.CreateInstance (typeof (IComparableOfTComparer <>).BindGenericParameters (new Type [] { typeof (T) }));
+			else
+				_default = new DefaultComparer ();
+		}
+		
+		
 		public abstract int Compare (T x, T y);
 	
-		static DefaultComparer _default;
+		static readonly Comparer <T> _default;
 		
-		[MonoTODO ("This is going to make a really slow comparer. We need to speed this up if T : ICompareable<T> create a class with a where clause of T : ICompareable <T>")]
-		public static Comparer<T> Default {
+		public static Comparer <T> Default {
 			get {
-				if (_default != null)
-					return _default;
-				return _default = new DefaultComparer ();
+				return _default;
 			}
 		}
 	
@@ -80,6 +86,19 @@ namespace System.Collections.Generic {
 			}
 		}
 	}
+	
+	class IComparableOfTComparer <T> : Comparer <T> where T : IComparable {
+		public override int Compare (T x, T y)
+		{
+			// `null' is less than any other ref type
+			if (x == null)
+				return y == null ? 0 : -1;
+			else if (y == null)
+				return 1;
+			
+			return x.CompareTo (y);
+		}
+	}
 
 }
 #endif

+ 33 - 9
mcs/class/corlib/System.Collections.Generic/EqualityComparer.cs

@@ -32,19 +32,25 @@ using System.Runtime.InteropServices;
 
 namespace System.Collections.Generic {
 	[Serializable]
-	public abstract class EqualityComparer<T> : IEqualityComparer<T> {
-			
+	public abstract class EqualityComparer <T> : IEqualityComparer <T> {
+		
+		static EqualityComparer ()
+		{
+			if (typeof (IEquatable <T>).IsAssignableFrom (typeof (T)))
+				_default = (EqualityComparer <T>) Activator.CreateInstance (typeof (IEquatableOfTEqualityComparer <>).BindGenericParameters (new Type [] { typeof (T) }));
+			else
+				_default = new DefaultComparer ();
+		}
+		
+		
 		public abstract int GetHashCode (T obj);
 		public abstract bool Equals (T x, T y);
 	
-		static DefaultComparer _default;
+		static readonly EqualityComparer <T> _default;
 		
-		[MonoTODO ("This is going to make a really slow comparer. We need to speed this up if T : ICompareable<T> create a class with a where clause of T : ICompareable <T>")]
-		public static EqualityComparer<T> Default {
+		public static EqualityComparer <T> Default {
 			get {
-				if (_default != null)
-					return _default;
-				return _default = new DefaultComparer ();
+				return _default;
 			}
 		}
 		
@@ -57,10 +63,28 @@ namespace System.Collections.Generic {
 	
 			public override bool Equals (T x, T y)
 			{
-				return Object.Equals (x, y);
+				if (x == null)
+					return y == null;
+				
+				return x.Equals (y);
 			}
 		}
 	}
+	
+	class IEquatableOfTEqualityComparer <T> : EqualityComparer <T> where T : IEquatable <T> {
 
+		public override int GetHashCode (T obj)
+		{
+			return obj.GetHashCode ();
+		}
+
+		public override bool Equals (T x, T y)
+		{
+			if (x == null)
+				return y == null;
+			
+			return x.Equals (y);
+		}
+	}
 }
 #endif