Skip to content

Commit

Permalink
Perf | avoid boxing of not null SqlBinary data and copying of binary …
Browse files Browse the repository at this point in the history
…data in SqlDataReader and TdsParser (#2308)
  • Loading branch information
wilbit committed Jan 19, 2024
1 parent 52e21cb commit 2f8c574
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1573,7 +1573,7 @@ override public Stream GetStream(int i)
else
{
// Grab already read data
data = _data[i].SqlBinary.Value;
data = _data[i].ByteArray;
}

// If non-sequential then we just have a read-only MemoryStream
Expand Down Expand Up @@ -2969,7 +2969,7 @@ private T GetFieldValueFromSqlBufferInternal<T>(SqlBuffer data, _SqlMetaData met
}
else
{
byte[] value = data.IsNull ? Array.Empty<byte>() : data.SqlBinary.Value;
byte[] value = data.IsNull ? Array.Empty<byte>() : data.ByteArray;
return (T)(object)new MemoryStream(value, writable: false);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5957,11 +5957,7 @@ internal bool DeserializeUnencryptedValue(SqlBuffer value, byte[] unencryptedByt
unencryptedBytes = bytes;
}

#if NET7_0_OR_GREATER
value.SqlBinary = SqlBinary.WrapBytes(unencryptedBytes);
#else
value.SqlBinary = SqlTypeWorkarounds.SqlBinaryCtor(unencryptedBytes, true); // doesn't copy the byte array
#endif
value.ByteArray = unencryptedBytes; // doesn't copy the byte array
break;
}

Expand Down Expand Up @@ -6154,11 +6150,7 @@ internal bool TryReadSqlValue(SqlBuffer value, SqlMetaDataPriv md, int length, T
}
else
{
#if NET7_0_OR_GREATER
value.SqlBinary = SqlBinary.WrapBytes(b);
#else
value.SqlBinary = SqlTypeWorkarounds.SqlBinaryCtor(b, true); // doesn't copy the byte array
#endif
value.ByteArray = b; // doesn't copy the byte array
}
break;

Expand Down Expand Up @@ -6451,12 +6443,8 @@ internal bool TryReadSqlValueInternal(SqlBuffer value, byte tdsType, int length,
{
return false;
}
#if NET7_0_OR_GREATER
value.SqlBinary = SqlBinary.WrapBytes(b);
#else
value.SqlBinary = SqlTypeWorkarounds.SqlBinaryCtor(b, true);
#endif

value.ByteArray = b; // doesn't copy byte array
break;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1770,7 +1770,7 @@ override public Stream GetStream(int i)
else
{
// Grab already read data
data = _data[i].SqlBinary.Value;
data = _data[i].ByteArray;
}

// If non-sequential then we just have a read-only MemoryStream
Expand Down Expand Up @@ -3308,7 +3308,7 @@ private T GetFieldValueFromSqlBufferInternal<T>(SqlBuffer data, _SqlMetaData met
}
else
{
byte[] value = data.IsNull ? Array.Empty<byte>() : data.SqlBinary.Value;
byte[] value = data.IsNull ? Array.Empty<byte>() : data.ByteArray;
return (T)(object)new MemoryStream(value, writable: false);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6741,7 +6741,7 @@ internal bool DeserializeUnencryptedValue(SqlBuffer value, byte[] unencryptedByt
unencryptedBytes = bytes;
}

value.SqlBinary = SqlTypeWorkarounds.SqlBinaryCtor(unencryptedBytes, true); // doesn't copy the byte array
value.ByteArray = unencryptedBytes; // doesn't copy the byte array
break;
}

Expand Down Expand Up @@ -6938,7 +6938,7 @@ internal bool TryReadSqlValue(SqlBuffer value,
}
else
{
value.SqlBinary = SqlTypeWorkarounds.SqlBinaryCtor(b, true); // doesn't copy the byte array
value.ByteArray = b; // doesn't copy the byte array
}
break;

Expand Down Expand Up @@ -7238,8 +7238,8 @@ internal bool TryReadSqlValueInternal(SqlBuffer value, byte tdsType, int length,
{
return false;
}
value.SqlBinary = SqlTypeWorkarounds.SqlBinaryCtor(b, true); // doesn't copy the byte array

value.ByteArray = b; // doesn't copy the byte array
break;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ SqlBuffer targetBuffer // destination
case SqlDbType.Image:
case SqlDbType.Timestamp:
case SqlDbType.VarBinary:
targetBuffer.SqlBinary = GetSqlBinary_Unchecked(sink, getters, ordinal);
targetBuffer.ByteArray = GetByteArray_Unchecked(sink, getters, ordinal);
break;
case SqlDbType.Bit:
targetBuffer.Boolean = GetBoolean_Unchecked(sink, getters, ordinal);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ internal struct Storage
private bool _isNull;
private StorageType _type;
private Storage _value;
private object _object; // String, SqlBinary, SqlCachedBuffer, SqlString, SqlXml
private object _object; // String, byte[] for SqlBinary, SqlCachedBuffer, SqlString, SqlXml

internal SqlBuffer()
{
Expand Down Expand Up @@ -179,7 +179,19 @@ internal byte[] ByteArray
get
{
ThrowIfNull();
return SqlBinary.Value;

if (StorageType.SqlBinary == _type)
{
return (byte[])_object;
}
return ((SqlBinary)SqlValue).Value; // anything else we haven't thought of goes through boxing.
}
set
{
Debug.Assert(IsEmpty, "setting value a second time?");
_object = value;
_type = StorageType.SqlBinary;
_isNull = value is null;
}
}

Expand Down Expand Up @@ -653,22 +665,16 @@ internal SqlBinary SqlBinary
{
get
{
if (StorageType.SqlBinary == _type)
if (IsNull)
{
if (IsNull)
{
return SqlBinary.Null;
}
return (SqlBinary)_object;
return SqlBinary.Null;
}
return (SqlBinary)SqlValue; // anything else we haven't thought of goes through boxing.
}
set
{
Debug.Assert(IsEmpty, "setting value a second time?");
_object = value;
_type = StorageType.SqlBinary;
_isNull = value.IsNull;

#if NET7_0_OR_GREATER
return SqlBinary.WrapBytes(ByteArray);
#else
return SqlTypeWorkarounds.SqlBinaryCtor(ByteArray, true); // doesn't copy the byte array
#endif
}
}

Expand Down

0 comments on commit 2f8c574

Please sign in to comment.