Index: MonoEncoding.cs
===================================================================
--- MonoEncoding.cs	(revision 61485)
+++ MonoEncoding.cs	(working copy)
@@ -7,6 +7,7 @@
 // Copyright (C) 2005 Novell, Inc.  http://www.novell.com
 //
 using System;
+using System.Reflection;
 using System.Runtime.InteropServices;
 using System.Text;
 
@@ -15,8 +16,23 @@
 	[Serializable]
 	public abstract class MonoEncoding : Encoding
 	{
+		protected delegate string AllocateStringDelegate(int length);
+
+		protected static readonly AllocateStringDelegate AllocateString;
 		readonly int win_code_page;
 
+		static MonoEncoding ()
+		{
+			Type [] types = new Type [] {typeof (int)};
+			Type stringType = typeof (string);
+			MethodInfo allocateStringMethod;
+
+			AllocateString = (allocateStringMethod = stringType.GetMethod ("InternalAllocateStr", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.ExactBinding,  null, types, null)) != null &&
+				allocateStringMethod.ReturnType == stringType ?
+				(AllocateStringDelegate) Delegate.CreateDelegate (typeof (AllocateStringDelegate), allocateStringMethod) :
+				new AllocateStringDelegate (FallbackAllocateString);
+		}
+
 		public MonoEncoding (int codePage)
 			: this (codePage, 0)
 		{
@@ -180,6 +196,11 @@
 		[CLSCompliant (false)]
 		public unsafe abstract int GetBytesImpl (char* chars, int charCount,
 			byte* bytes, int byteCount);
+
+		private static string FallbackAllocateString(int length)
+		{
+			return new string ((char) 0, length);
+		}
 	}
 
 		public abstract class MonoEncoder : Encoder
Index: ByteEncoding.cs
===================================================================
--- ByteEncoding.cs	(revision 61485)
+++ ByteEncoding.cs	(working copy)
@@ -58,6 +58,9 @@
 						   int windowsCodePage)
 			: base(codePage)
 			{
+				if (toChars.Length != byte.MaxValue + 1)
+					throw new ArgumentException("toChars");
+
 				this.toChars = toChars;
 				this.encodingName = encodingName;
 				this.bodyName = bodyName;
@@ -314,7 +317,7 @@
 			}
 
 	// Decode a buffer of bytes into a string.
-	public override String GetString(byte[] bytes, int index, int count)
+	public unsafe override String GetString(byte[] bytes, int index, int count)
 			{
 				if(bytes == null)
 				{
@@ -330,29 +333,31 @@
 					throw new ArgumentOutOfRangeException
 						("count", Strings.GetString("ArgRange_Array"));
 				}
-				StringBuilder s = new StringBuilder();
-				char[] cvt = toChars;
-				while(count-- > 0)
-				{
-					s.Append(cvt[(int)(bytes[index++])]);
-				}
-				return s.ToString();
+
+				if (count == 0)
+					return string.Empty;
+
+				string s = AllocateString (count);
+
+				fixed (byte* bytePtr = bytes)
+					fixed (char* charPtr = s)
+						fixed (char* cvt = toChars) {
+							byte* b = bytePtr;
+							char* c = charPtr;
+							while(count-- != 0)
+								*(c++) = cvt[*(b++)];
+						}
+
+				return s;
 			}
-	public override String GetString(byte[] bytes)
+	public unsafe override String GetString(byte[] bytes)
 			{
 				if(bytes == null)
 				{
 					throw new ArgumentNullException("bytes");
 				}
-				int count = bytes.Length;
-				int posn = 0;
-				StringBuilder s = new StringBuilder();
-				char[] cvt = toChars;
-				while(count-- > 0)
-				{
-					s.Append(cvt[(int)(bytes[posn++])]);
-				}
-				return s.ToString();
+
+				return GetString (bytes, 0, bytes.Length);
 			}
 
 #if !ECMA_COMPAT
