Performance fix for double/float on read

pull/288/head
csharptest 14 years ago committed by rogerk
parent 2772dfe8a1
commit 4ba365d793
  1. 101
      src/ProtocolBuffers.Test/CompatTests/CompatibilityTests.cs
  2. 23
      src/ProtocolBuffers.Test/CompatTests/TextCompatibilityTests.cs
  3. 19
      src/ProtocolBuffers/CodedInputStream.cs

@ -15,107 +15,6 @@ namespace Google.ProtocolBuffers.CompatTests
where TMessage : IMessageLite<TMessage, TBuilder>
where TBuilder : IBuilderLite<TMessage, TBuilder>;
#region RunBenchmark
protected void RunBenchmark<TMessage, TBuilder>(byte[] buffer, bool write)
where TMessage : IMessageLite<TMessage, TBuilder>
where TBuilder : IBuilderLite<TMessage, TBuilder>, new()
{
TBuilder builder = new TBuilder();
TMessage message = new TBuilder().MergeFrom(buffer).Build();
System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
//simple warm-up
object content = SerializeMessage<TMessage, TBuilder>(message);
Assert.AreEqual(message, DeerializeMessage<TMessage, TBuilder>(content, new TBuilder(), ExtensionRegistry.Empty).Build());
//timming
long time = 0, sample = 1;
while (time < 100)
{
sample *= 10;
watch.Reset();
watch.Start();
if (write)
{
for (int i = 0; i < sample; i++)
SerializeMessage<TMessage, TBuilder>(message);
}
else
{
for (int i = 0; i < sample; i++)
DeerializeMessage<TMessage, TBuilder>(content, builder, ExtensionRegistry.Empty);
}
watch.Stop();
time = watch.ElapsedMilliseconds;
}
ulong rounds = (ulong)((100.0 / watch.ElapsedMilliseconds) * sample);
//test
watch.Reset();
watch.Start();
if (write)
{
for (ulong i = 0; i < rounds; i++)
SerializeMessage<TMessage, TBuilder>(message);
}
else
{
for (ulong i = 0; i < rounds; i++)
DeerializeMessage<TMessage, TBuilder>(content, builder, ExtensionRegistry.Empty);
}
watch.Stop();
System.Diagnostics.Trace.TraceInformation(
"\r\n{0} {4} {5} {3:n0} rps ({1:n0} rounds in {2:n0} ms)", typeof(TMessage).Name, rounds,
watch.ElapsedMilliseconds, (1000.0 / watch.ElapsedMilliseconds) * (double)rounds, TestName, write ? " write" : " read");
GC.GetTotalMemory(true);
GC.WaitForPendingFinalizers();
}
[Test]
public virtual void Message1OptimizeSizeWriterPerf()
{
RunBenchmark<SizeMessage1, SizeMessage1.Builder>(TestResources.google_message1, true);
}
[Test]
public virtual void Message1OptimizeSpeedWriterPerf()
{
RunBenchmark<SpeedMessage1, SpeedMessage1.Builder>(TestResources.google_message1, true);
}
[Test]
public virtual void Message2OptimizeSizeWriterPerf()
{
RunBenchmark<SizeMessage2, SizeMessage2.Builder>(TestResources.google_message2, true);
}
[Test]
public virtual void Message2OptimizeSpeedWriterPerf()
{
RunBenchmark<SpeedMessage2, SpeedMessage2.Builder>(TestResources.google_message2, true);
}
[Test]
public virtual void Message1OptimizeSizeReadPerf()
{
RunBenchmark<SizeMessage1, SizeMessage1.Builder>(TestResources.google_message1, false);
}
[Test]
public virtual void Message1OptimizeSpeedReadPerf()
{
RunBenchmark<SpeedMessage1, SpeedMessage1.Builder>(TestResources.google_message1, false);
}
[Test]
public virtual void Message2OptimizeSizeReadPerf()
{
RunBenchmark<SizeMessage2, SizeMessage2.Builder>(TestResources.google_message2, false);
}
[Test]
public virtual void Message2OptimizeSpeedReadPerf()
{
RunBenchmark<SpeedMessage2, SpeedMessage2.Builder>(TestResources.google_message2, false);
}
#endregion
[Test]
public virtual void RoundTripMessage1OptimizeSize()
{

@ -22,17 +22,6 @@ namespace Google.ProtocolBuffers.CompatTests
return builder;
}
[Test, Explicit, Description("This test can take a very long time to run.")]
public override void Message2OptimizeSizeReadPerf()
{
base.Message2OptimizeSizeReadPerf();
}
[Test, Explicit, Description("This test can take a very long time to run.")]
public override void Message2OptimizeSpeedReadPerf()
{
base.Message2OptimizeSpeedReadPerf();
}
[Test, Explicit, Description("This test can take a very long time to run.")]
public override void RoundTripMessage2OptimizeSize()
{
@ -44,17 +33,5 @@ namespace Google.ProtocolBuffers.CompatTests
{
base.RoundTripMessage2OptimizeSpeed();
}
[Test, Explicit, Description("This test can take a very long time to run.")]
public override void Message2OptimizeSizeWriterPerf()
{
base.Message2OptimizeSizeWriterPerf();
}
[Test, Explicit, Description("This test can take a very long time to run.")]
public override void Message2OptimizeSpeedWriterPerf()
{
base.Message2OptimizeSpeedWriterPerf();
}
}
}

@ -204,26 +204,41 @@ namespace Google.ProtocolBuffers
public bool ReadDouble(ref double value)
{
#if SILVERLIGHT2 || COMPACT_FRAMEWORK_35
if (BitConverter.IsLittleEndian && 8 <= bufferSize - bufferPos)
{
value = BitConverter.ToDouble(buffer, bufferPos);
bufferPos += 8;
}
else
{
byte[] rawBytes = ReadRawBytes(8);
if (!BitConverter.IsLittleEndian)
Array.Reverse(rawBytes);
value = BitConverter.ToDouble(rawBytes, 0);
return true;
}
#else
value = BitConverter.Int64BitsToDouble((long) ReadRawLittleEndian64());
return true;
#endif
return true;
}
/// <summary>
/// Read a float field from the stream.
/// </summary>
public bool ReadFloat(ref float value)
{
if (BitConverter.IsLittleEndian && 4 <= bufferSize - bufferPos)
{
value = BitConverter.ToSingle(buffer, bufferPos);
bufferPos += 4;
}
else
{
byte[] rawBytes = ReadRawBytes(4);
if (!BitConverter.IsLittleEndian)
Array.Reverse(rawBytes);
value = BitConverter.ToSingle(rawBytes, 0);
}
return true;
}

Loading…
Cancel
Save