Author: lluis
Date: 2005-03-23 14:11:05 -0500 (Wed, 23 Mar 2005)
New Revision: 42162

Modified:
   
trunk/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryCommon.cs
   
trunk/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ChangeLog
   
trunk/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs
   
trunk/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs
Log:
2005-03-23  Lluis Sanchez Gual  <[EMAIL PROTECTED]>

        * BinaryCommon.cs: Added helper method for swapping bytes.
        * ObjectReader.cs:
        * ObjectWriter.cs: Implemented serialization of arrays of primitive
        types using Buffer.BlockCopy to create byffers of data that is written/
        read in a single call. It's much faster now.



Modified: 
trunk/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryCommon.cs
===================================================================
--- 
trunk/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryCommon.cs
       2005-03-23 18:50:29 UTC (rev 42161)
+++ 
trunk/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryCommon.cs
       2005-03-23 19:11:05 UTC (rev 42162)
@@ -117,7 +117,29 @@
 
                                throw new SerializationException ("Type " + 
type + " is not marked as Serializable.");
                        }
-               }
+               }
+               
+               public static void SwapBytes (byte[] byteArray, int size, int 
dataSize)
+               {
+                       byte b;
+                       if (dataSize == 8) {
+                               for (int n=0; n<size; n+=8) {
+                                       b = byteArray [n]; byteArray [n] = 
byteArray [n + 7]; byteArray [n + 7] = b;
+                                       b = byteArray [n+1]; byteArray [n+1] = 
byteArray [n + 6]; byteArray [n + 6] = b;
+                                       b = byteArray [n+2]; byteArray [n+2] = 
byteArray [n + 5]; byteArray [n + 5] = b;
+                                       b = byteArray [n+3]; byteArray [n+3] = 
byteArray [n + 4]; byteArray [n + 4] = b;
+                               }
+                       } else if (dataSize == 4) {
+                               for (int n=0; n<size; n+=4) {
+                                       b = byteArray [n]; byteArray [n] = 
byteArray [n + 3]; byteArray [n + 3] = b;
+                                       b = byteArray [n+1]; byteArray [n+1] = 
byteArray [n + 2]; byteArray [n + 2] = b;
+                               }
+                       } else if (dataSize == 2) {
+                               for (int n=0; n<size; n+=2) {
+                                       b = byteArray [n]; byteArray [n] = 
byteArray [n + 1]; byteArray [n + 1] = b;
+                               }
+                       }
+               }
        }
 
        internal enum BinaryElement : byte

Modified: 
trunk/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ChangeLog
===================================================================
--- 
trunk/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ChangeLog 
    2005-03-23 18:50:29 UTC (rev 42161)
+++ 
trunk/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ChangeLog 
    2005-03-23 19:11:05 UTC (rev 42162)
@@ -1,3 +1,11 @@
+2005-03-23  Lluis Sanchez Gual  <[EMAIL PROTECTED]>
+
+       * BinaryCommon.cs: Added helper method for swapping bytes.
+       * ObjectReader.cs:
+       * ObjectWriter.cs: Implemented serialization of arrays of primitive
+       types using Buffer.BlockCopy to create byffers of data that is written/
+       read in a single call. It's much faster now.
+
 2005-03-01  Lluis Sanchez Gual  <[EMAIL PROTECTED]>
 
        * BinaryCommon.cs: Found the meaning of two unknown binary elements.

Modified: 
trunk/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs
===================================================================
--- 
trunk/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs
       2005-03-23 18:50:29 UTC (rev 42161)
+++ 
trunk/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs
       2005-03-23 19:11:05 UTC (rev 42162)
@@ -56,7 +56,9 @@
 
                object _lastObject = null;
                long _lastObjectID = 0;
-               long _rootObjectID = 0;
+               long _rootObjectID = 0;
+               byte[] arrayBuffer;
+               int ArrayBufferLength = 4096;
 
                class TypeMetadata
                {
@@ -368,12 +370,26 @@
                                }
 
                                case TypeCode.Byte: {
-                                       val = reader.ReadBytes (length);
+                                       byte[] arr = new byte [length];
+                                       int pos = 0;
+                                       while (pos < length) {
+                                               int nr = reader.Read (arr, pos, 
length - pos);
+                                               if (nr == 0) break;
+                                               pos += nr;
+                                       }
+                                       val = arr;
                                        break;
                                }
 
                                case TypeCode.Char: {
-                                       val = reader.ReadChars (length);
+                                       char[] arr = new char [length];
+                                       int pos = 0;
+                                       while (pos < length) {
+                                               int nr = reader.Read (arr, pos, 
length - pos);
+                                               if (nr == 0) break;
+                                               pos += nr;
+                                       }
+                                       val = arr;
                                        break;
                                }
 
@@ -386,70 +402,97 @@
 
                                case TypeCode.Decimal: {
                                        Decimal[] arr = new Decimal [length];
-                                       for (int n = 0; n < length; n++) arr 
[n] = Decimal.Parse (reader.ReadString(), CultureInfo.InvariantCulture);
+                                       for (int n = 0; n < length; n++) arr 
[n] = reader.ReadDecimal();
                                        val = arr;
                                        break;
                                }
 
                                case TypeCode.Double: {
-                                       Double[] arr = new Double [length];
-                                       for (int n = 0; n < length; n++) arr 
[n] = reader.ReadDouble();
+                                       Double[] arr = new Double [length];
+                                       if (length > 2)
+                                               BlockRead (reader, arr, 8);
+                                       else
+                                               for (int n = 0; n < length; 
n++) arr [n] = reader.ReadDouble();
                                        val = arr;
                                        break;
                                }
 
                                case TypeCode.Int16: {
                                        short[] arr = new short [length];
-                                       for (int n = 0; n < length; n++) arr 
[n] = reader.ReadInt16();
+                                       if (length > 2)
+                                               BlockRead (reader, arr, 2);
+                                       else
+                                               for (int n = 0; n < length; 
n++) arr [n] = reader.ReadInt16();
                                        val = arr;
                                        break;
                                }
 
                                case TypeCode.Int32: {
                                        int[] arr = new int [length];
-                                       for (int n = 0; n < length; n++) arr 
[n] = reader.ReadInt32();
+                                       if (length > 2)
+                                               BlockRead (reader, arr, 4);
+                                       else
+                                               for (int n = 0; n < length; 
n++) arr [n] = reader.ReadInt32();
                                        val = arr;
                                        break;
                                }
 
                                case TypeCode.Int64: {
-                                       long[] arr = new long [length];
-                                       for (int n = 0; n < length; n++) arr 
[n] = reader.ReadInt64();
+                                       long[] arr = new long [length];
+                                       if (length > 2)
+                                               BlockRead (reader, arr, 8);
+                                       else
+                                               for (int n = 0; n < length; 
n++) arr [n] = reader.ReadInt64();
                                        val = arr;
                                        break;
                                }
 
                                case TypeCode.SByte: {
                                        sbyte[] arr = new sbyte [length];
-                                       for (int n = 0; n < length; n++) arr 
[n] = reader.ReadSByte();
+                                       if (length > 2)
+                                               BlockRead (reader, arr, 1);
+                                       else
+                                               for (int n = 0; n < length; 
n++) arr [n] = reader.ReadSByte();
                                        val = arr;
                                        break;
                                }
 
                                case TypeCode.Single: {
                                        float[] arr = new float [length];
-                                       for (int n = 0; n < length; n++) arr 
[n] = reader.ReadSingle();
+                                       if (length > 2)
+                                               BlockRead (reader, arr, 4);
+                                       else
+                                               for (int n = 0; n < length; 
n++) arr [n] = reader.ReadSingle();
                                        val = arr;
                                        break;
                                }
 
                                case TypeCode.UInt16: {
                                        ushort[] arr = new ushort [length];
-                                       for (int n = 0; n < length; n++) arr 
[n] = reader.ReadUInt16();
+                                       if (length > 2)
+                                               BlockRead (reader, arr, 2);
+                                       else
+                                               for (int n = 0; n < length; 
n++) arr [n] = reader.ReadUInt16();
                                        val = arr;
                                        break;
                                }
 
                                case TypeCode.UInt32: {
                                        uint[] arr = new uint [length];
-                                       for (int n = 0; n < length; n++) arr 
[n] = reader.ReadUInt32();
+                                       if (length > 2)
+                                               BlockRead (reader, arr, 4);
+                                       else
+                                               for (int n = 0; n < length; 
n++) arr [n] = reader.ReadUInt32();
                                        val = arr;
                                        break;
                                }
 
                                case TypeCode.UInt64: {
                                        ulong[] arr = new ulong [length];
-                                       for (int n = 0; n < length; n++) arr 
[n] = reader.ReadUInt64();
+                                       if (length > 2)
+                                               BlockRead (reader, arr, 8);
+                                       else
+                                               for (int n = 0; n < length; 
n++) arr [n] = reader.ReadUInt64();
                                        val = arr;
                                        break;
                                }
@@ -474,6 +517,33 @@
                        }                       
                }
 
+               private void BlockRead (BinaryReader reader, Array array, int 
dataSize)
+               {
+                       int totalSize = Buffer.ByteLength (array);
+                       
+                       if (arrayBuffer == null || (totalSize > 
arrayBuffer.Length && arrayBuffer.Length != ArrayBufferLength))
+                               arrayBuffer = new byte [totalSize <= 
ArrayBufferLength ? totalSize : ArrayBufferLength];
+                       
+                       int pos = 0;
+                       while (totalSize > 0) {
+                               int size = totalSize < arrayBuffer.Length ? 
totalSize : arrayBuffer.Length;
+                               int ap = 0;
+                               do {
+                                       int nr = reader.Read (arrayBuffer, ap, 
size - ap);
+                                       if (nr == 0) break;
+                                       ap += nr;
+                               } while (ap < size);
+                               
+                               if (!BitConverter.IsLittleEndian && dataSize > 
1)
+                                       BinaryCommon.SwapBytes (arrayBuffer, 
size, dataSize);
+
+                               Buffer.BlockCopy (arrayBuffer, 0, array, pos, 
size);
+                               totalSize -= size;
+                               pos += size;
+                       }
+               }
+               
+
                private void ReadArrayOfObject (BinaryReader reader, out long 
objectId, out object array)
                {
                        ReadSimpleArray (reader, typeof (object), out objectId, 
out array);

Modified: 
trunk/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs
===================================================================
--- 
trunk/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs
       2005-03-23 18:50:29 UTC (rev 42161)
+++ 
trunk/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs
       2005-03-23 19:11:05 UTC (rev 42162)
@@ -223,6 +223,8 @@
                StreamingContext _context;
                FormatterAssemblyStyle _assemblyFormat;
                FormatterTypeStyle _typeFormat;
+               byte[] arrayBuffer;
+               int ArrayBufferLength = 4096;
                
                class MetadataReference
                {
@@ -544,8 +546,7 @@
                                        break;
 
                                case TypeCode.Char:
-                                       foreach (char item in (char[]) array)
-                                               writer.Write (item);
+                                       writer.Write ((char[]) array);
                                        break;
 
                                case TypeCode.DateTime: 
@@ -558,49 +559,76 @@
                                                writer.Write (item);
                                        break;
 
-                               case TypeCode.Double:
-                                       foreach (double item in (double[]) 
array)
-                                               writer.Write (item);
+                               case TypeCode.Double:
+                                       if (array.Length > 2)
+                                               BlockWrite (writer, array, 8);
+                                       else
+                                               foreach (double item in 
(double[]) array)
+                                                       writer.Write (item);
                                        break;
 
                                case TypeCode.Int16:
-                                       foreach (short item in (short[]) array)
-                                               writer.Write (item);
+                                       if (array.Length > 2)
+                                               BlockWrite (writer, array, 2);
+                                       else
+                                               foreach (short item in 
(short[]) array)
+                                                       writer.Write (item);
                                        break;
 
-                               case TypeCode.Int32:
-                                       foreach (int item in (int[]) array)
-                                               writer.Write (item);
+                               case TypeCode.Int32:
+                                       if (array.Length > 2)
+                                               BlockWrite (writer, array, 4);
+                                       else
+                                               foreach (int item in (int[]) 
array)
+                                                       writer.Write (item);
                                        break;
 
-                               case TypeCode.Int64:
-                                       foreach (long item in (long[]) array)
-                                               writer.Write (item);
+                               case TypeCode.Int64:
+                                       if (array.Length > 2)
+                                               BlockWrite (writer, array, 8);
+                                       else
+                                               foreach (long item in (long[]) 
array)
+                                                       writer.Write (item);
                                        break;
 
                                case TypeCode.SByte:
-                                       foreach (sbyte item in (sbyte[]) array)
-                                               writer.Write (item);
+                                       if (array.Length > 2)
+                                               BlockWrite (writer, array, 1);
+                                       else
+                                               foreach (sbyte item in 
(sbyte[]) array)
+                                                       writer.Write (item);
                                        break;
 
                                case TypeCode.Single:
-                                       foreach (float item in (float[]) array)
-                                               writer.Write (item);
+                                       if (array.Length > 2)
+                                               BlockWrite (writer, array, 4);
+                                       else
+                                               foreach (float item in 
(float[]) array)
+                                                       writer.Write (item);
                                        break;
 
                                case TypeCode.UInt16:
-                                       foreach (ushort item in (ushort[]) 
array)
-                                               writer.Write (item);
+                                       if (array.Length > 2)
+                                               BlockWrite (writer, array, 2);
+                                       else
+                                               foreach (ushort item in 
(ushort[]) array)
+                                                       writer.Write (item);
                                        break;
 
                                case TypeCode.UInt32:
-                                       foreach (uint item in (uint[]) array)
-                                               writer.Write (item);
+                                       if (array.Length > 2)
+                                               BlockWrite (writer, array, 4);
+                                       else
+                                               foreach (uint item in (uint[]) 
array)
+                                                       writer.Write (item);
                                        break;
 
                                case TypeCode.UInt64:
-                                       foreach (ulong item in (ulong[]) array)
-                                               writer.Write (item);
+                                       if (array.Length > 2)
+                                               BlockWrite (writer, array, 8);
+                                       else
+                                               foreach (ulong item in 
(ulong[]) array)
+                                                       writer.Write (item);
                                        break;
 
                                case TypeCode.String:
@@ -617,6 +645,27 @@
                                                throw new NotSupportedException 
("Unsupported primitive type: " + elementType.FullName);
                                        break;
                        }                       
+               }
+               
+               private void BlockWrite (BinaryWriter writer, Array array, int 
dataSize)
+               {
+                       int totalSize = Buffer.ByteLength (array);
+                       
+                       if (arrayBuffer == null || (totalSize > 
arrayBuffer.Length && arrayBuffer.Length != ArrayBufferLength))
+                               arrayBuffer = new byte [totalSize <= 
ArrayBufferLength ? totalSize : ArrayBufferLength];
+                       
+                       int pos = 0;
+                       while (totalSize > 0) {
+                               int size = totalSize < arrayBuffer.Length ? 
totalSize : arrayBuffer.Length;
+                               Buffer.BlockCopy (array, pos, arrayBuffer, 0, 
size);
+                               
+                               if (!BitConverter.IsLittleEndian && dataSize > 
1)
+                                       BinaryCommon.SwapBytes (arrayBuffer, 
size, dataSize);
+                               
+                               writer.Write (arrayBuffer, 0, size);
+                               totalSize -= size;
+                               pos += size;
+                       }
                }
 
                private void WriteSingleDimensionArrayElements (BinaryWriter 
writer, Array array, Type elementType)

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to