Hello,

Could someone please review or comment on this simple patch I've already
posted twice? Thanks!

- Juraj
--- Begin Message ---
Hello,

Attached you'll find a patch which reduces the number of allocations
done in String.Replace and StringBuilder.Replace.

All unit tests pass, ChangeLog entries are included.
Please review.

- Juraj


PS: I've already posted this patch back in June, but this time I've
leaving out the controversial part.
http://lists.ximian.com/pipermail/mono-devel-list/2008-June/028239.html
Index: corlib/System/ChangeLog
===================================================================
--- corlib/System/ChangeLog	(revision 112532)
+++ corlib/System/ChangeLog	(working copy)
@@ -1,3 +1,8 @@
+2008-09-08  Juraj Skripsky  <[EMAIL PROTECTED]>
+
+	* String.cs (ReplaceUnchecked): Avoid any unnecessary work and 
+	string allocations by returning early when no oldValue was found.
+
 2008-09-07  Miguel de Icaza  <[EMAIL PROTECTED]>
 
 	* TermInfoDriver.cs: Add support for updating the size of the
Index: corlib/System/String.cs
===================================================================
--- corlib/System/String.cs	(revision 112532)
+++ corlib/System/String.cs	(working copy)
@@ -1689,6 +1689,8 @@
 					}
 					i = found + oldValue.length;
 				}
+				if (count == 0)
+					return this;
 				int nlen = this.length + ((newValue.length - oldValue.length) * count);
 				String tmp = InternalAllocateStr (nlen);
 
Index: corlib/System.Text/StringBuilder.cs
===================================================================
--- corlib/System.Text/StringBuilder.cs	(revision 112532)
+++ corlib/System.Text/StringBuilder.cs	(working copy)
@@ -309,15 +309,22 @@
 			if (oldValue.Length == 0)
 				throw new ArgumentException ("The old value cannot be zero length.");
 
-			// TODO: OPTIMIZE!
-			string replace = _str.Substring(startIndex, count).Replace(oldValue, newValue);
+			string substr = _str.Substring(startIndex, count);
+			string replace = substr.Replace(oldValue, newValue);
+			// return early if no oldValue was found
+			if ((object) replace == (object) substr)
+				return this;
 
 			InternalEnsureCapacity (replace.Length + (_length - count));
 
-			string end = _str.Substring (startIndex + count, _length - startIndex - count );
+			// shift end part
+			if (replace.Length < count)
+				String.CharCopy (_str, startIndex + replace.Length, _str, startIndex + count, _length - startIndex  - count);
+			else if (replace.Length > count)
+				String.CharCopyReverse (_str, startIndex + replace.Length, _str, startIndex + count, _length - startIndex  - count);
 
+			// copy middle part back into _str
 			String.CharCopy (_str, startIndex, replace, 0, replace.Length);
-			String.CharCopy (_str, startIndex + replace.Length, end, 0, end.Length);
 			
 			_length = replace.Length + (_length - count);
 
Index: corlib/System.Text/ChangeLog
===================================================================
--- corlib/System.Text/ChangeLog	(revision 112532)
+++ corlib/System.Text/ChangeLog	(working copy)
@@ -1,3 +1,8 @@
+2008-09-08  Juraj Skripsky  <[EMAIL PROTECTED]>
+
+	* StringBuilder.cs (Replace): Return early when no oldValue was 
+	found. Avoid extra string allocations.   
+
 2008-07-03  Andreas Nahr  <[EMAIL PROTECTED]>
 
 	* UTF8Encoding.cs: Fix parameter names, Remove unfounded TODO
_______________________________________________
Mono-devel-list mailing list
[email protected]
http://lists.ximian.com/mailman/listinfo/mono-devel-list

--- End Message ---
_______________________________________________
Mono-devel-list mailing list
[email protected]
http://lists.ximian.com/mailman/listinfo/mono-devel-list

Reply via email to