Commit 2772dfe8 authored by csharptest's avatar csharptest Committed by rogerk

Performance fix for float/double write bytes. Performance fix, do not use Array.Copy.

parent 0e2d144e
...@@ -87,6 +87,7 @@ namespace Google.ProtocolBuffers.ProtoBench ...@@ -87,6 +87,7 @@ namespace Google.ProtocolBuffers.ProtoBench
Console.Error.WriteLine("(You can specify multiple pairs of descriptor type name and input data.)"); Console.Error.WriteLine("(You can specify multiple pairs of descriptor type name and input data.)");
return 1; return 1;
} }
bool success = true; bool success = true;
for (int i = 0; i < args.Length; i += 2) for (int i = 0; i < args.Length; i += 2)
{ {
...@@ -94,7 +95,7 @@ namespace Google.ProtocolBuffers.ProtoBench ...@@ -94,7 +95,7 @@ namespace Google.ProtocolBuffers.ProtoBench
} }
return success ? 0 : 1; return success ? 0 : 1;
} }
/// <summary> /// <summary>
/// Runs a single test. Error messages are displayed to Console.Error, and the return value indicates /// Runs a single test. Error messages are displayed to Console.Error, and the return value indicates
/// general success/failure. /// general success/failure.
...@@ -185,7 +186,7 @@ namespace Google.ProtocolBuffers.ProtoBench ...@@ -185,7 +186,7 @@ namespace Google.ProtocolBuffers.ProtoBench
double first = (iterations * dataSize) / (elapsed.TotalSeconds * 1024 * 1024); double first = (iterations * dataSize) / (elapsed.TotalSeconds * 1024 * 1024);
if (Verbose) Console.WriteLine("Round ---: Count = {1,6}, Bps = {2,8:f3}", 0, iterations, first); if (Verbose) Console.WriteLine("Round ---: Count = {1,6}, Bps = {2,8:f3}", 0, iterations, first);
elapsed = TimeSpan.Zero; elapsed = TimeSpan.Zero;
int max = FastTest ? 30 : 100; int max = FastTest ? 10 : 30;
while (runs < max) while (runs < max)
{ {
......
...@@ -123,7 +123,7 @@ namespace Google.ProtocolBuffers ...@@ -123,7 +123,7 @@ namespace Google.ProtocolBuffers
public static ByteString CopyFrom(byte[] bytes, int offset, int count) public static ByteString CopyFrom(byte[] bytes, int offset, int count)
{ {
byte[] portion = new byte[count]; byte[] portion = new byte[count];
Array.Copy(bytes, offset, portion, 0, count); Bytes.Copy(bytes, offset, portion, 0, count);
return new ByteString(portion); return new ByteString(portion);
} }
...@@ -259,9 +259,9 @@ namespace Google.ProtocolBuffers ...@@ -259,9 +259,9 @@ namespace Google.ProtocolBuffers
/// <summary> /// <summary>
/// Copies the entire byte array to the destination array provided at the offset specified. /// Copies the entire byte array to the destination array provided at the offset specified.
/// </summary> /// </summary>
public void CopyTo(Array array, int position) public void CopyTo(byte[] array, int position)
{ {
Array.Copy(bytes, 0, array, position, bytes.Length); Bytes.Copy(bytes, 0, array, position, bytes.Length);
} }
/// <summary> /// <summary>
......
namespace Google.ProtocolBuffers
{
/// <summary>
/// Provides a utility routine to copy small arrays much more quickly than Buffer.BlockCopy
/// </summary>
static class Bytes
{
/// <summary>
/// The threshold above which you should use Buffer.BlockCopy rather than Bytes.Copy
/// </summary>
const int CopyThreshold = 12;
/// <summary>
/// Determines which copy routine to use based on the number of bytes to be copied.
/// </summary>
public static void Copy(byte[] src, int srcOffset, byte[] dst, int dstOffset, int count)
{
if (count > CopyThreshold)
global::System.Buffer.BlockCopy(src, srcOffset, dst, dstOffset, count);
else
ByteCopy(src, srcOffset, dst, dstOffset, count);
}
/// <summary>
/// Copyies the bytes provided with a for loop, faster when there are only a few bytes to copy
/// </summary>
public static void ByteCopy(byte[] src, int srcOffset, byte[] dst, int dstOffset, int count)
{
int stop = srcOffset + count;
for (int i = srcOffset; i < stop; i++)
dst[dstOffset++] = src[i];
}
}
}
\ No newline at end of file
...@@ -1225,7 +1225,7 @@ namespace Google.ProtocolBuffers ...@@ -1225,7 +1225,7 @@ namespace Google.ProtocolBuffers
{ {
// We have all the bytes we need already. // We have all the bytes we need already.
byte[] bytes = new byte[size]; byte[] bytes = new byte[size];
Array.Copy(buffer, bufferPos, bytes, 0, size); Bytes.Copy(buffer, bufferPos, bytes, 0, size);
bufferPos += size; bufferPos += size;
return bytes; return bytes;
} }
...@@ -1237,7 +1237,7 @@ namespace Google.ProtocolBuffers ...@@ -1237,7 +1237,7 @@ namespace Google.ProtocolBuffers
// First copy what we have. // First copy what we have.
byte[] bytes = new byte[size]; byte[] bytes = new byte[size];
int pos = bufferSize - bufferPos; int pos = bufferSize - bufferPos;
Array.Copy(buffer, bufferPos, bytes, 0, pos); Bytes.Copy(buffer, bufferPos, bytes, 0, pos);
bufferPos = bufferSize; bufferPos = bufferSize;
// We want to use RefillBuffer() and then copy from the buffer into our // We want to use RefillBuffer() and then copy from the buffer into our
...@@ -1247,13 +1247,13 @@ namespace Google.ProtocolBuffers ...@@ -1247,13 +1247,13 @@ namespace Google.ProtocolBuffers
while (size - pos > bufferSize) while (size - pos > bufferSize)
{ {
Array.Copy(buffer, 0, bytes, pos, bufferSize); Buffer.BlockCopy(buffer, 0, bytes, pos, bufferSize);
pos += bufferSize; pos += bufferSize;
bufferPos = bufferSize; bufferPos = bufferSize;
RefillBuffer(true); RefillBuffer(true);
} }
Array.Copy(buffer, 0, bytes, pos, size - pos); Bytes.Copy(buffer, 0, bytes, pos, size - pos);
bufferPos = size - pos; bufferPos = size - pos;
return bytes; return bytes;
...@@ -1305,12 +1305,12 @@ namespace Google.ProtocolBuffers ...@@ -1305,12 +1305,12 @@ namespace Google.ProtocolBuffers
// Start by copying the leftover bytes from this.buffer. // Start by copying the leftover bytes from this.buffer.
int newPos = originalBufferSize - originalBufferPos; int newPos = originalBufferSize - originalBufferPos;
Array.Copy(buffer, originalBufferPos, bytes, 0, newPos); Bytes.Copy(buffer, originalBufferPos, bytes, 0, newPos);
// And now all the chunks. // And now all the chunks.
foreach (byte[] chunk in chunks) foreach (byte[] chunk in chunks)
{ {
Array.Copy(chunk, 0, bytes, newPos, chunk.Length); Buffer.BlockCopy(chunk, 0, bytes, newPos, chunk.Length);
newPos += chunk.Length; newPos += chunk.Length;
} }
......
...@@ -38,6 +38,7 @@ using System; ...@@ -38,6 +38,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Runtime.InteropServices;
using System.Text; using System.Text;
using Google.ProtocolBuffers.Descriptors; using Google.ProtocolBuffers.Descriptors;
...@@ -648,7 +649,20 @@ namespace Google.ProtocolBuffers ...@@ -648,7 +649,20 @@ namespace Google.ProtocolBuffers
byte[] rawBytes = BitConverter.GetBytes(value); byte[] rawBytes = BitConverter.GetBytes(value);
if (!BitConverter.IsLittleEndian) if (!BitConverter.IsLittleEndian)
Array.Reverse(rawBytes); Array.Reverse(rawBytes);
WriteRawBytes(rawBytes, 0, 8);
if (limit - position >= 8)
{
buffer[position++] = rawBytes[0];
buffer[position++] = rawBytes[1];
buffer[position++] = rawBytes[2];
buffer[position++] = rawBytes[3];
buffer[position++] = rawBytes[4];
buffer[position++] = rawBytes[5];
buffer[position++] = rawBytes[6];
buffer[position++] = rawBytes[7];
}
else
WriteRawBytes(rawBytes, 0, 8);
#else #else
WriteRawLittleEndian64((ulong)BitConverter.DoubleToInt64Bits(value)); WriteRawLittleEndian64((ulong)BitConverter.DoubleToInt64Bits(value));
#endif #endif
...@@ -662,7 +676,16 @@ namespace Google.ProtocolBuffers ...@@ -662,7 +676,16 @@ namespace Google.ProtocolBuffers
byte[] rawBytes = BitConverter.GetBytes(value); byte[] rawBytes = BitConverter.GetBytes(value);
if (!BitConverter.IsLittleEndian) if (!BitConverter.IsLittleEndian)
Array.Reverse(rawBytes); Array.Reverse(rawBytes);
WriteRawBytes(rawBytes, 0, 4);
if (limit - position >= 4)
{
buffer[position++] = rawBytes[0];
buffer[position++] = rawBytes[1];
buffer[position++] = rawBytes[2];
buffer[position++] = rawBytes[3];
}
else
WriteRawBytes(rawBytes, 0, 4);
} }
/// <summary> /// <summary>
...@@ -985,7 +1008,7 @@ namespace Google.ProtocolBuffers ...@@ -985,7 +1008,7 @@ namespace Google.ProtocolBuffers
{ {
if (limit - position >= length) if (limit - position >= length)
{ {
Array.Copy(value, offset, buffer, position, length); Bytes.Copy(value, offset, buffer, position, length);
// We have room in the current buffer. // We have room in the current buffer.
position += length; position += length;
} }
...@@ -994,7 +1017,7 @@ namespace Google.ProtocolBuffers ...@@ -994,7 +1017,7 @@ namespace Google.ProtocolBuffers
// Write extends past current buffer. Fill the rest of this buffer and // Write extends past current buffer. Fill the rest of this buffer and
// flush. // flush.
int bytesWritten = limit - position; int bytesWritten = limit - position;
Array.Copy(value, offset, buffer, position, bytesWritten); Bytes.Copy(value, offset, buffer, position, bytesWritten);
offset += bytesWritten; offset += bytesWritten;
length -= bytesWritten; length -= bytesWritten;
position = limit; position = limit;
...@@ -1006,7 +1029,7 @@ namespace Google.ProtocolBuffers ...@@ -1006,7 +1029,7 @@ namespace Google.ProtocolBuffers
if (length <= limit) if (length <= limit)
{ {
// Fits in new buffer. // Fits in new buffer.
Array.Copy(value, offset, buffer, 0, length); Bytes.Copy(value, offset, buffer, 0, length);
position = length; position = length;
} }
else else
......
...@@ -99,6 +99,7 @@ ...@@ -99,6 +99,7 @@
<Compile Include="AbstractMessageLite.cs"> <Compile Include="AbstractMessageLite.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="Bytes.cs" />
<Compile Include="ByteString.cs" /> <Compile Include="ByteString.cs" />
<Compile Include="Collections\Enumerables.cs" /> <Compile Include="Collections\Enumerables.cs" />
<Compile Include="Collections\IPopsicleList.cs" /> <Compile Include="Collections\IPopsicleList.cs" />
......
...@@ -78,6 +78,7 @@ ...@@ -78,6 +78,7 @@
<ItemGroup> <ItemGroup>
<Compile Include="AbstractBuilderLite.cs" /> <Compile Include="AbstractBuilderLite.cs" />
<Compile Include="AbstractMessageLite.cs" /> <Compile Include="AbstractMessageLite.cs" />
<Compile Include="Bytes.cs" />
<Compile Include="CodedOutputStream.ComputeSize.cs" /> <Compile Include="CodedOutputStream.ComputeSize.cs" />
<Compile Include="Collections\Dictionaries.cs" /> <Compile Include="Collections\Dictionaries.cs" />
<Compile Include="Collections\Enumerables.cs" /> <Compile Include="Collections\Enumerables.cs" />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment