Commit 79d127c8 authored by Wouter van Oortmerssen's avatar Wouter van Oortmerssen Committed by GitHub

Merge pull request #2133 from evolutional/cs-bounds-check

C#: added #define BYTEBUFFER_NO_BOUNDS_CHECK 
parents 96ab6ade 4802e8a2
...@@ -14,7 +14,20 @@ ...@@ -14,7 +14,20 @@
* limitations under the License. * limitations under the License.
*/ */
//#define UNSAFE_BYTEBUFFER // uncomment this line to use faster ByteBuffer // There are 2 #defines that have an impact on performance of this ByteBuffer implementation
//
// UNSAFE_BYTEBUFFER
// This will use unsafe code to manipulate the underlying byte array. This
// can yield a reasonable performance increase.
//
// BYTEBUFFER_NO_BOUNDS_CHECK
// This will disable the bounds check asserts to the byte array. This can
// yield a small performance gain in normal code..
//
// Using UNSAFE_BYTEBUFFER and BYTEBUFFER_NO_BOUNDS_CHECK together can yield a
// performance gain of ~15% for some operations, however doing so is potentially
// dangerous. Do so at your own risk!
//
using System; using System;
...@@ -22,9 +35,6 @@ namespace FlatBuffers ...@@ -22,9 +35,6 @@ namespace FlatBuffers
{ {
/// <summary> /// <summary>
/// Class to mimic Java's ByteBuffer which is used heavily in Flatbuffers. /// Class to mimic Java's ByteBuffer which is used heavily in Flatbuffers.
/// If your execution environment allows unsafe code, you should enable
/// unsafe code in your project and #define UNSAFE_BYTEBUFFER to use a
/// MUCH faster version of ByteBuffer.
/// </summary> /// </summary>
public class ByteBuffer public class ByteBuffer
{ {
...@@ -126,11 +136,14 @@ namespace FlatBuffers ...@@ -126,11 +136,14 @@ namespace FlatBuffers
} }
#endif // !UNSAFE_BYTEBUFFER #endif // !UNSAFE_BYTEBUFFER
private void AssertOffsetAndLength(int offset, int length) private void AssertOffsetAndLength(int offset, int length)
{ {
#if !BYTEBUFFER_NO_BOUNDS_CHECK
if (offset < 0 || if (offset < 0 ||
offset > _buffer.Length - length) offset > _buffer.Length - length)
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
#endif
} }
public void PutSbyte(int offset, sbyte value) public void PutSbyte(int offset, sbyte value)
...@@ -200,7 +213,6 @@ namespace FlatBuffers ...@@ -200,7 +213,6 @@ namespace FlatBuffers
public unsafe void PutUlong(int offset, ulong value) public unsafe void PutUlong(int offset, ulong value)
{ {
AssertOffsetAndLength(offset, sizeof(ulong)); AssertOffsetAndLength(offset, sizeof(ulong));
fixed (byte* ptr = _buffer) fixed (byte* ptr = _buffer)
{ {
*(ulong*)(ptr + offset) = BitConverter.IsLittleEndian *(ulong*)(ptr + offset) = BitConverter.IsLittleEndian
......
...@@ -40,6 +40,7 @@ namespace FlatBuffers.Test ...@@ -40,6 +40,7 @@ namespace FlatBuffers.Test
Assert.AreEqual((byte)99, buffer[0]); Assert.AreEqual((byte)99, buffer[0]);
} }
#if !BYTEBUFFER_NO_BOUNDS_CHECK
[FlatBuffersTestMethod] [FlatBuffersTestMethod]
public void ByteBuffer_PutByteCannotPutAtOffsetPastLength() public void ByteBuffer_PutByteCannotPutAtOffsetPastLength()
{ {
...@@ -47,6 +48,7 @@ namespace FlatBuffers.Test ...@@ -47,6 +48,7 @@ namespace FlatBuffers.Test
var uut = new ByteBuffer(buffer); var uut = new ByteBuffer(buffer);
Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutByte(1, 99)); Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutByte(1, 99));
} }
#endif
[FlatBuffersTestMethod] [FlatBuffersTestMethod]
public void ByteBuffer_PutShortPopulatesBufferCorrectly() public void ByteBuffer_PutShortPopulatesBufferCorrectly()
...@@ -60,6 +62,7 @@ namespace FlatBuffers.Test ...@@ -60,6 +62,7 @@ namespace FlatBuffers.Test
Assert.AreEqual((byte)0, buffer[1]); Assert.AreEqual((byte)0, buffer[1]);
} }
#if !BYTEBUFFER_NO_BOUNDS_CHECK
[FlatBuffersTestMethod] [FlatBuffersTestMethod]
public void ByteBuffer_PutShortCannotPutAtOffsetPastLength() public void ByteBuffer_PutShortCannotPutAtOffsetPastLength()
{ {
...@@ -67,7 +70,9 @@ namespace FlatBuffers.Test ...@@ -67,7 +70,9 @@ namespace FlatBuffers.Test
var uut = new ByteBuffer(buffer); var uut = new ByteBuffer(buffer);
Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutShort(2, 99)); Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutShort(2, 99));
} }
#endif
#if !BYTEBUFFER_NO_BOUNDS_CHECK
[FlatBuffersTestMethod] [FlatBuffersTestMethod]
public void ByteBuffer_PutShortChecksLength() public void ByteBuffer_PutShortChecksLength()
{ {
...@@ -83,6 +88,7 @@ namespace FlatBuffers.Test ...@@ -83,6 +88,7 @@ namespace FlatBuffers.Test
var uut = new ByteBuffer(buffer); var uut = new ByteBuffer(buffer);
Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutShort(1, 99)); Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutShort(1, 99));
} }
#endif
[FlatBuffersTestMethod] [FlatBuffersTestMethod]
public void ByteBuffer_PutIntPopulatesBufferCorrectly() public void ByteBuffer_PutIntPopulatesBufferCorrectly()
...@@ -98,6 +104,7 @@ namespace FlatBuffers.Test ...@@ -98,6 +104,7 @@ namespace FlatBuffers.Test
Assert.AreEqual(0x0A, buffer[3]); Assert.AreEqual(0x0A, buffer[3]);
} }
#if !BYTEBUFFER_NO_BOUNDS_CHECK
[FlatBuffersTestMethod] [FlatBuffersTestMethod]
public void ByteBuffer_PutIntCannotPutAtOffsetPastLength() public void ByteBuffer_PutIntCannotPutAtOffsetPastLength()
{ {
...@@ -121,6 +128,7 @@ namespace FlatBuffers.Test ...@@ -121,6 +128,7 @@ namespace FlatBuffers.Test
var uut = new ByteBuffer(buffer); var uut = new ByteBuffer(buffer);
Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutInt(2, 0x0A0B0C0D)); Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutInt(2, 0x0A0B0C0D));
} }
#endif
[FlatBuffersTestMethod] [FlatBuffersTestMethod]
public void ByteBuffer_PutLongPopulatesBufferCorrectly() public void ByteBuffer_PutLongPopulatesBufferCorrectly()
...@@ -140,6 +148,7 @@ namespace FlatBuffers.Test ...@@ -140,6 +148,7 @@ namespace FlatBuffers.Test
Assert.AreEqual(0x01, buffer[7]); Assert.AreEqual(0x01, buffer[7]);
} }
#if !BYTEBUFFER_NO_BOUNDS_CHECK
[FlatBuffersTestMethod] [FlatBuffersTestMethod]
public void ByteBuffer_PutLongCannotPutAtOffsetPastLength() public void ByteBuffer_PutLongCannotPutAtOffsetPastLength()
{ {
...@@ -163,6 +172,7 @@ namespace FlatBuffers.Test ...@@ -163,6 +172,7 @@ namespace FlatBuffers.Test
var uut = new ByteBuffer(buffer); var uut = new ByteBuffer(buffer);
Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutLong(2, 0x010203040A0B0C0D)); Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutLong(2, 0x010203040A0B0C0D));
} }
#endif
[FlatBuffersTestMethod] [FlatBuffersTestMethod]
public void ByteBuffer_GetByteReturnsCorrectData() public void ByteBuffer_GetByteReturnsCorrectData()
...@@ -173,6 +183,7 @@ namespace FlatBuffers.Test ...@@ -173,6 +183,7 @@ namespace FlatBuffers.Test
Assert.AreEqual((byte)99, uut.Get(0)); Assert.AreEqual((byte)99, uut.Get(0));
} }
#if !BYTEBUFFER_NO_BOUNDS_CHECK
[FlatBuffersTestMethod] [FlatBuffersTestMethod]
public void ByteBuffer_GetByteChecksOffset() public void ByteBuffer_GetByteChecksOffset()
{ {
...@@ -180,6 +191,7 @@ namespace FlatBuffers.Test ...@@ -180,6 +191,7 @@ namespace FlatBuffers.Test
var uut = new ByteBuffer(buffer); var uut = new ByteBuffer(buffer);
Assert.Throws<ArgumentOutOfRangeException>(()=>uut.Get(1)); Assert.Throws<ArgumentOutOfRangeException>(()=>uut.Get(1));
} }
#endif
[FlatBuffersTestMethod] [FlatBuffersTestMethod]
public void ByteBuffer_GetShortReturnsCorrectData() public void ByteBuffer_GetShortReturnsCorrectData()
...@@ -191,6 +203,7 @@ namespace FlatBuffers.Test ...@@ -191,6 +203,7 @@ namespace FlatBuffers.Test
Assert.AreEqual(1, uut.GetShort(0)); Assert.AreEqual(1, uut.GetShort(0));
} }
#if !BYTEBUFFER_NO_BOUNDS_CHECK
[FlatBuffersTestMethod] [FlatBuffersTestMethod]
public void ByteBuffer_GetShortChecksOffset() public void ByteBuffer_GetShortChecksOffset()
{ {
...@@ -206,6 +219,7 @@ namespace FlatBuffers.Test ...@@ -206,6 +219,7 @@ namespace FlatBuffers.Test
var uut = new ByteBuffer(buffer); var uut = new ByteBuffer(buffer);
Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetShort(1)); Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetShort(1));
} }
#endif
[FlatBuffersTestMethod] [FlatBuffersTestMethod]
public void ByteBuffer_GetIntReturnsCorrectData() public void ByteBuffer_GetIntReturnsCorrectData()
...@@ -219,6 +233,7 @@ namespace FlatBuffers.Test ...@@ -219,6 +233,7 @@ namespace FlatBuffers.Test
Assert.AreEqual(0x0A0B0C0D, uut.GetInt(0)); Assert.AreEqual(0x0A0B0C0D, uut.GetInt(0));
} }
#if !BYTEBUFFER_NO_BOUNDS_CHECK
[FlatBuffersTestMethod] [FlatBuffersTestMethod]
public void ByteBuffer_GetIntChecksOffset() public void ByteBuffer_GetIntChecksOffset()
{ {
...@@ -234,6 +249,7 @@ namespace FlatBuffers.Test ...@@ -234,6 +249,7 @@ namespace FlatBuffers.Test
var uut = new ByteBuffer(buffer); var uut = new ByteBuffer(buffer);
Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetInt(0)); Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetInt(0));
} }
#endif
[FlatBuffersTestMethod] [FlatBuffersTestMethod]
public void ByteBuffer_GetLongReturnsCorrectData() public void ByteBuffer_GetLongReturnsCorrectData()
...@@ -251,6 +267,7 @@ namespace FlatBuffers.Test ...@@ -251,6 +267,7 @@ namespace FlatBuffers.Test
Assert.AreEqual(0x010203040A0B0C0D, uut.GetLong(0)); Assert.AreEqual(0x010203040A0B0C0D, uut.GetLong(0));
} }
#if !BYTEBUFFER_NO_BOUNDS_CHECK
[FlatBuffersTestMethod] [FlatBuffersTestMethod]
public void ByteBuffer_GetLongChecksOffset() public void ByteBuffer_GetLongChecksOffset()
{ {
...@@ -266,6 +283,7 @@ namespace FlatBuffers.Test ...@@ -266,6 +283,7 @@ namespace FlatBuffers.Test
var uut = new ByteBuffer(buffer); var uut = new ByteBuffer(buffer);
Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetLong(0)); Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetLong(0));
} }
#endif
[FlatBuffersTestMethod] [FlatBuffersTestMethod]
public void ByteBuffer_ReverseBytesUshort() public void ByteBuffer_ReverseBytesUshort()
......
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