aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ProtoBench/Program.cs5
-rw-r--r--src/ProtocolBuffers/ByteString.cs6
-rw-r--r--src/ProtocolBuffers/Bytes.cs32
-rw-r--r--src/ProtocolBuffers/CodedInputStream.cs12
-rw-r--r--src/ProtocolBuffers/CodedOutputStream.cs33
-rw-r--r--src/ProtocolBuffers/ProtocolBuffers.csproj1
-rw-r--r--src/ProtocolBuffers/ProtocolBuffersLite.csproj1
7 files changed, 74 insertions, 16 deletions
diff --git a/src/ProtoBench/Program.cs b/src/ProtoBench/Program.cs
index 7d91bbed..36f7850d 100644
--- a/src/ProtoBench/Program.cs
+++ b/src/ProtoBench/Program.cs
@@ -87,6 +87,7 @@ namespace Google.ProtocolBuffers.ProtoBench
Console.Error.WriteLine("(You can specify multiple pairs of descriptor type name and input data.)");
return 1;
}
+
bool success = true;
for (int i = 0; i < args.Length; i += 2)
{
@@ -94,7 +95,7 @@ namespace Google.ProtocolBuffers.ProtoBench
}
return success ? 0 : 1;
}
-
+
/// <summary>
/// Runs a single test. Error messages are displayed to Console.Error, and the return value indicates
/// general success/failure.
@@ -185,7 +186,7 @@ namespace Google.ProtocolBuffers.ProtoBench
double first = (iterations * dataSize) / (elapsed.TotalSeconds * 1024 * 1024);
if (Verbose) Console.WriteLine("Round ---: Count = {1,6}, Bps = {2,8:f3}", 0, iterations, first);
elapsed = TimeSpan.Zero;
- int max = FastTest ? 30 : 100;
+ int max = FastTest ? 10 : 30;
while (runs < max)
{
diff --git a/src/ProtocolBuffers/ByteString.cs b/src/ProtocolBuffers/ByteString.cs
index e645a9f2..06708af7 100644
--- a/src/ProtocolBuffers/ByteString.cs
+++ b/src/ProtocolBuffers/ByteString.cs
@@ -123,7 +123,7 @@ namespace Google.ProtocolBuffers
public static ByteString CopyFrom(byte[] bytes, int offset, int count)
{
byte[] portion = new byte[count];
- Array.Copy(bytes, offset, portion, 0, count);
+ Bytes.Copy(bytes, offset, portion, 0, count);
return new ByteString(portion);
}
@@ -259,9 +259,9 @@ namespace Google.ProtocolBuffers
/// <summary>
/// Copies the entire byte array to the destination array provided at the offset specified.
/// </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>
diff --git a/src/ProtocolBuffers/Bytes.cs b/src/ProtocolBuffers/Bytes.cs
new file mode 100644
index 00000000..88bc16f8
--- /dev/null
+++ b/src/ProtocolBuffers/Bytes.cs
@@ -0,0 +1,32 @@
+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
diff --git a/src/ProtocolBuffers/CodedInputStream.cs b/src/ProtocolBuffers/CodedInputStream.cs
index 74fa9475..4f9bdc23 100644
--- a/src/ProtocolBuffers/CodedInputStream.cs
+++ b/src/ProtocolBuffers/CodedInputStream.cs
@@ -1225,7 +1225,7 @@ namespace Google.ProtocolBuffers
{
// We have all the bytes we need already.
byte[] bytes = new byte[size];
- Array.Copy(buffer, bufferPos, bytes, 0, size);
+ Bytes.Copy(buffer, bufferPos, bytes, 0, size);
bufferPos += size;
return bytes;
}
@@ -1237,7 +1237,7 @@ namespace Google.ProtocolBuffers
// First copy what we have.
byte[] bytes = new byte[size];
int pos = bufferSize - bufferPos;
- Array.Copy(buffer, bufferPos, bytes, 0, pos);
+ Bytes.Copy(buffer, bufferPos, bytes, 0, pos);
bufferPos = bufferSize;
// We want to use RefillBuffer() and then copy from the buffer into our
@@ -1247,13 +1247,13 @@ namespace Google.ProtocolBuffers
while (size - pos > bufferSize)
{
- Array.Copy(buffer, 0, bytes, pos, bufferSize);
+ Buffer.BlockCopy(buffer, 0, bytes, pos, bufferSize);
pos += bufferSize;
bufferPos = bufferSize;
RefillBuffer(true);
}
- Array.Copy(buffer, 0, bytes, pos, size - pos);
+ Bytes.Copy(buffer, 0, bytes, pos, size - pos);
bufferPos = size - pos;
return bytes;
@@ -1305,12 +1305,12 @@ namespace Google.ProtocolBuffers
// Start by copying the leftover bytes from this.buffer.
int newPos = originalBufferSize - originalBufferPos;
- Array.Copy(buffer, originalBufferPos, bytes, 0, newPos);
+ Bytes.Copy(buffer, originalBufferPos, bytes, 0, newPos);
// And now all the 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;
}
diff --git a/src/ProtocolBuffers/CodedOutputStream.cs b/src/ProtocolBuffers/CodedOutputStream.cs
index 31032058..bd508661 100644
--- a/src/ProtocolBuffers/CodedOutputStream.cs
+++ b/src/ProtocolBuffers/CodedOutputStream.cs
@@ -38,6 +38,7 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
+using System.Runtime.InteropServices;
using System.Text;
using Google.ProtocolBuffers.Descriptors;
@@ -648,7 +649,20 @@ namespace Google.ProtocolBuffers
byte[] rawBytes = BitConverter.GetBytes(value);
if (!BitConverter.IsLittleEndian)
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
WriteRawLittleEndian64((ulong)BitConverter.DoubleToInt64Bits(value));
#endif
@@ -662,7 +676,16 @@ namespace Google.ProtocolBuffers
byte[] rawBytes = BitConverter.GetBytes(value);
if (!BitConverter.IsLittleEndian)
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>
@@ -985,7 +1008,7 @@ namespace Google.ProtocolBuffers
{
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.
position += length;
}
@@ -994,7 +1017,7 @@ namespace Google.ProtocolBuffers
// Write extends past current buffer. Fill the rest of this buffer and
// flush.
int bytesWritten = limit - position;
- Array.Copy(value, offset, buffer, position, bytesWritten);
+ Bytes.Copy(value, offset, buffer, position, bytesWritten);
offset += bytesWritten;
length -= bytesWritten;
position = limit;
@@ -1006,7 +1029,7 @@ namespace Google.ProtocolBuffers
if (length <= limit)
{
// Fits in new buffer.
- Array.Copy(value, offset, buffer, 0, length);
+ Bytes.Copy(value, offset, buffer, 0, length);
position = length;
}
else
diff --git a/src/ProtocolBuffers/ProtocolBuffers.csproj b/src/ProtocolBuffers/ProtocolBuffers.csproj
index a059ca39..cf212909 100644
--- a/src/ProtocolBuffers/ProtocolBuffers.csproj
+++ b/src/ProtocolBuffers/ProtocolBuffers.csproj
@@ -99,6 +99,7 @@
<Compile Include="AbstractMessageLite.cs">
<SubType>Code</SubType>
</Compile>
+ <Compile Include="Bytes.cs" />
<Compile Include="ByteString.cs" />
<Compile Include="Collections\Enumerables.cs" />
<Compile Include="Collections\IPopsicleList.cs" />
diff --git a/src/ProtocolBuffers/ProtocolBuffersLite.csproj b/src/ProtocolBuffers/ProtocolBuffersLite.csproj
index 936a6950..fc1c7f64 100644
--- a/src/ProtocolBuffers/ProtocolBuffersLite.csproj
+++ b/src/ProtocolBuffers/ProtocolBuffersLite.csproj
@@ -78,6 +78,7 @@
<ItemGroup>
<Compile Include="AbstractBuilderLite.cs" />
<Compile Include="AbstractMessageLite.cs" />
+ <Compile Include="Bytes.cs" />
<Compile Include="CodedOutputStream.ComputeSize.cs" />
<Compile Include="Collections\Dictionaries.cs" />
<Compile Include="Collections\Enumerables.cs" />