Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
When result-set contains multiple rows, in order to get field value, the columns details are checked for each field parsing. This PR permit to set parsing method once for the result-set. This doesn't change much in terms of performance, but still not negligible. Performance results: ``` [Benchmark] public async Task getInt64() { using var cmd = Connection.CreateCommand(); cmd.CommandText = "SELECT * FROM seq_1_to_100000"; using var reader = await cmd.ExecuteReaderAsync(); long total = 0; do { while (await reader.ReadAsync()) { total += reader.GetInt64(0); } } while (await reader.NextResultAsync()); } ``` Initial results: ``` | Method | Library | Mean | Error | |--------- |--------------- |---------:|---------:| | getInt64 | MySqlConnector | 17.91 ms | 0.149 ms | ``` PR results: ``` | Method | Library | Mean | Error | |--------- |--------------- |---------:|---------:| | getInt64 | MySqlConnector | 17.59 ms | 0.125 ms | ```
- Loading branch information
Showing
44 changed files
with
1,290 additions
and
356 deletions.
There are no files selected for viewing
20 changes: 20 additions & 0 deletions
20
src/MySqlConnector/ColumnReaders/BinaryBooleanColumnReader.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
namespace MySqlConnector.ColumnReaders; | ||
using System.Buffers.Text; | ||
using MySqlConnector.Protocol.Payloads; | ||
using MySqlConnector.Protocol.Serialization; | ||
using MySqlConnector.Utilities; | ||
|
||
internal sealed class BinaryBooleanColumnReader : IColumnReader | ||
{ | ||
internal static BinaryBooleanColumnReader Instance { get; } = new BinaryBooleanColumnReader(); | ||
|
||
public object ReadValue(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
return data[0] != 0; | ||
} | ||
|
||
public int ReadInt32(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
return data[0] != 0 ? 1 : 0; | ||
} | ||
} |
74 changes: 74 additions & 0 deletions
74
src/MySqlConnector/ColumnReaders/BinaryDateTimeColumnReader.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
namespace MySqlConnector.ColumnReaders; | ||
|
||
using System; | ||
using System.Buffers.Text; | ||
using System.Runtime.InteropServices; | ||
using System.Text; | ||
using MySqlConnector.Core; | ||
using MySqlConnector.Protocol.Payloads; | ||
using MySqlConnector.Protocol.Serialization; | ||
using MySqlConnector.Utilities; | ||
|
||
internal sealed class BinaryDateTimeColumnReader : IColumnReader | ||
{ | ||
private bool allowZeroDateTime; | ||
private bool convertZeroDateTime; | ||
private DateTimeKind dateTimeKind; | ||
internal BinaryDateTimeColumnReader(MySqlConnection connection) | ||
{ | ||
this.allowZeroDateTime = connection.AllowZeroDateTime; | ||
this.convertZeroDateTime = connection.ConvertZeroDateTime; | ||
this.dateTimeKind = connection.DateTimeKind; | ||
} | ||
|
||
public object ReadValue(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
if (data.Length == 0) | ||
{ | ||
if (this.convertZeroDateTime) | ||
return DateTime.MinValue; | ||
if (this.allowZeroDateTime) | ||
return default(MySqlDateTime); | ||
throw new InvalidCastException("Unable to convert MySQL date/time to System.DateTime."); | ||
} | ||
|
||
int year = data[0] + data[1] * 256; | ||
int month = data[2]; | ||
int day = data[3]; | ||
|
||
int hour, minute, second; | ||
if (data.Length <= 4) | ||
{ | ||
hour = 0; | ||
minute = 0; | ||
second = 0; | ||
} | ||
else | ||
{ | ||
hour = data[4]; | ||
minute = data[5]; | ||
second = data[6]; | ||
} | ||
|
||
var microseconds = data.Length <= 7 ? 0 : MemoryMarshal.Read<int>(data[7..]); | ||
|
||
try | ||
{ | ||
return this.allowZeroDateTime ? (object) new MySqlDateTime(year, month, day, hour, minute, second, microseconds) : | ||
#if NET7_0_OR_GREATER | ||
new DateTime(year, month, day, hour, minute, second, microseconds / 1000, microseconds % 1000, this.dateTimeKind); | ||
#else | ||
new DateTime(year, month, day, hour, minute, second, microseconds / 1000, this.dateTimeKind).AddTicks(microseconds % 1000 * 10); | ||
#endif | ||
} | ||
catch (Exception ex) | ||
{ | ||
throw new FormatException($"Couldn't interpret value as a valid DateTime: {Encoding.UTF8.GetString(data)}", ex); | ||
} | ||
} | ||
|
||
public int ReadInt32(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
throw new InvalidCastException($"Can't convert {columnDefinition.ColumnType} to Int32"); | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
src/MySqlConnector/ColumnReaders/BinaryDoubleColumnReader.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
namespace MySqlConnector.ColumnReaders; | ||
using System.Buffers.Text; | ||
using System.Runtime.InteropServices; | ||
using MySqlConnector.Protocol.Payloads; | ||
using MySqlConnector.Protocol.Serialization; | ||
using MySqlConnector.Utilities; | ||
|
||
internal sealed class BinaryDoubleColumnReader : IColumnReader | ||
{ | ||
internal static BinaryDoubleColumnReader Instance { get; } = new BinaryDoubleColumnReader(); | ||
|
||
public object ReadValue(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
return MemoryMarshal.Read<double>(data); | ||
} | ||
|
||
public int ReadInt32(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
throw new InvalidCastException($"Can't convert {columnDefinition.ColumnType} to Int32"); | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
src/MySqlConnector/ColumnReaders/BinaryFloatColumnReader.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
namespace MySqlConnector.ColumnReaders; | ||
using System.Buffers.Text; | ||
using System.Runtime.InteropServices; | ||
using MySqlConnector.Protocol.Payloads; | ||
using MySqlConnector.Protocol.Serialization; | ||
using MySqlConnector.Utilities; | ||
|
||
internal sealed class BinaryFloatColumnReader : IColumnReader | ||
{ | ||
internal static BinaryFloatColumnReader Instance { get; } = new BinaryFloatColumnReader(); | ||
|
||
public object ReadValue(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
return MemoryMarshal.Read<float>(data); | ||
} | ||
|
||
public int ReadInt32(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
throw new InvalidCastException($"Can't convert {columnDefinition.ColumnType} to Int32"); | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
src/MySqlConnector/ColumnReaders/BinarySignedInt16ColumnReader.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
namespace MySqlConnector.ColumnReaders; | ||
using System.Buffers.Text; | ||
using System.Runtime.InteropServices; | ||
using MySqlConnector.Protocol.Payloads; | ||
using MySqlConnector.Protocol.Serialization; | ||
using MySqlConnector.Utilities; | ||
|
||
internal sealed class BinarySignedInt16ColumnReader : IColumnReader | ||
{ | ||
internal static BinarySignedInt16ColumnReader Instance { get; } = new BinarySignedInt16ColumnReader(); | ||
|
||
public object ReadValue(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
return MemoryMarshal.Read<short>(data); | ||
} | ||
|
||
public int ReadInt32(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
return (int) MemoryMarshal.Read<short>(data); | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
src/MySqlConnector/ColumnReaders/BinarySignedInt32ColumnReader.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
namespace MySqlConnector.ColumnReaders; | ||
using System.Buffers.Text; | ||
using System.Runtime.InteropServices; | ||
using MySqlConnector.Protocol.Payloads; | ||
using MySqlConnector.Protocol.Serialization; | ||
using MySqlConnector.Utilities; | ||
|
||
internal sealed class BinarySignedInt32ColumnReader : IColumnReader | ||
{ | ||
internal static BinarySignedInt32ColumnReader Instance { get; } = new BinarySignedInt32ColumnReader(); | ||
|
||
public object ReadValue(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
return MemoryMarshal.Read<int>(data); | ||
} | ||
|
||
public int ReadInt32(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
return MemoryMarshal.Read<int>(data); | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
src/MySqlConnector/ColumnReaders/BinarySignedInt64ColumnReader.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
namespace MySqlConnector.ColumnReaders; | ||
using System.Buffers.Text; | ||
using System.Runtime.InteropServices; | ||
using MySqlConnector.Protocol.Payloads; | ||
using MySqlConnector.Protocol.Serialization; | ||
using MySqlConnector.Utilities; | ||
|
||
internal sealed class BinarySignedInt64ColumnReader : IColumnReader | ||
{ | ||
internal static BinarySignedInt64ColumnReader Instance { get; } = new BinarySignedInt64ColumnReader(); | ||
|
||
public object ReadValue(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
return MemoryMarshal.Read<long>(data); | ||
} | ||
|
||
public int ReadInt32(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
return checked((int) MemoryMarshal.Read<long>(data)); | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
src/MySqlConnector/ColumnReaders/BinarySignedInt8ColumnReader.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
namespace MySqlConnector.ColumnReaders; | ||
using System.Buffers.Text; | ||
using MySqlConnector.Protocol.Payloads; | ||
using MySqlConnector.Protocol.Serialization; | ||
using MySqlConnector.Utilities; | ||
|
||
internal sealed class BinarySignedInt8ColumnReader : IColumnReader | ||
{ | ||
internal static BinarySignedInt8ColumnReader Instance { get; } = new BinarySignedInt8ColumnReader(); | ||
|
||
public object ReadValue(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
return (sbyte) data[0]; | ||
} | ||
|
||
public int ReadInt32(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
return (int) (sbyte) data[0]; | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
src/MySqlConnector/ColumnReaders/BinaryTimeColumnReader.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
namespace MySqlConnector.ColumnReaders; | ||
using System.Buffers.Text; | ||
using System.Runtime.InteropServices; | ||
using MySqlConnector.Protocol.Payloads; | ||
using MySqlConnector.Protocol.Serialization; | ||
using MySqlConnector.Utilities; | ||
|
||
internal sealed class BinaryTimeColumnReader : IColumnReader | ||
{ | ||
internal static BinaryTimeColumnReader Instance { get; } = new BinaryTimeColumnReader(); | ||
|
||
public object ReadValue(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
if (data.Length == 0) | ||
return TimeSpan.Zero; | ||
|
||
var isNegative = data[0]; | ||
var days = MemoryMarshal.Read<int>(data[1..]); | ||
var hours = (int) data[5]; | ||
var minutes = (int) data[6]; | ||
var seconds = (int) data[7]; | ||
var microseconds = data.Length == 8 ? 0 : MemoryMarshal.Read<int>(data[8..]); | ||
|
||
if (isNegative != 0) | ||
{ | ||
days = -days; | ||
hours = -hours; | ||
minutes = -minutes; | ||
seconds = -seconds; | ||
microseconds = -microseconds; | ||
} | ||
|
||
#if NET7_0_OR_GREATER | ||
return new TimeSpan(days, hours, minutes, seconds, microseconds / 1000, microseconds % 1000); | ||
#else | ||
return new TimeSpan(days, hours, minutes, seconds) + TimeSpan.FromTicks(microseconds * 10); | ||
#endif | ||
} | ||
|
||
public int ReadInt32(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
throw new InvalidCastException($"Can't convert {columnDefinition.ColumnType} to Int32"); | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
src/MySqlConnector/ColumnReaders/BinaryUnsignedInt16ColumnReader.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
namespace MySqlConnector.ColumnReaders; | ||
using System.Buffers.Text; | ||
using System.Runtime.InteropServices; | ||
using MySqlConnector.Protocol.Payloads; | ||
using MySqlConnector.Protocol.Serialization; | ||
using MySqlConnector.Utilities; | ||
|
||
internal sealed class BinaryUnsignedInt16ColumnReader : IColumnReader | ||
{ | ||
internal static BinaryUnsignedInt16ColumnReader Instance { get; } = new BinaryUnsignedInt16ColumnReader(); | ||
|
||
public object ReadValue(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
return MemoryMarshal.Read<ushort>(data); | ||
} | ||
|
||
public int ReadInt32(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
return (int) MemoryMarshal.Read<ushort>(data); | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
src/MySqlConnector/ColumnReaders/BinaryUnsignedInt32ColumnReader.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
namespace MySqlConnector.ColumnReaders; | ||
using System.Buffers.Text; | ||
using System.Runtime.InteropServices; | ||
using MySqlConnector.Protocol.Payloads; | ||
using MySqlConnector.Protocol.Serialization; | ||
using MySqlConnector.Utilities; | ||
|
||
internal sealed class BinaryUnsignedInt32ColumnReader : IColumnReader | ||
{ | ||
internal static BinaryUnsignedInt32ColumnReader Instance { get; } = new BinaryUnsignedInt32ColumnReader(); | ||
|
||
public object ReadValue(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
return MemoryMarshal.Read<uint>(data); | ||
} | ||
|
||
public int ReadInt32(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
return checked((int) MemoryMarshal.Read<uint>(data)); | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
src/MySqlConnector/ColumnReaders/BinaryUnsignedInt64ColumnReader.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
namespace MySqlConnector.ColumnReaders; | ||
using System.Buffers.Text; | ||
using System.Runtime.InteropServices; | ||
using MySqlConnector.Protocol.Payloads; | ||
using MySqlConnector.Protocol.Serialization; | ||
using MySqlConnector.Utilities; | ||
|
||
internal sealed class BinaryUnsignedInt64ColumnReader : IColumnReader | ||
{ | ||
internal static BinaryUnsignedInt64ColumnReader Instance { get; } = new BinaryUnsignedInt64ColumnReader(); | ||
|
||
public object ReadValue(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
return MemoryMarshal.Read<ulong>(data); | ||
} | ||
|
||
public int ReadInt32(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
return checked((int) MemoryMarshal.Read<ulong>(data)); | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
src/MySqlConnector/ColumnReaders/BinaryUnsignedInt8ColumnReader.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
namespace MySqlConnector.ColumnReaders; | ||
using System.Buffers.Text; | ||
using MySqlConnector.Protocol.Payloads; | ||
using MySqlConnector.Protocol.Serialization; | ||
using MySqlConnector.Utilities; | ||
|
||
internal sealed class BinaryUnsignedInt8ColumnReader : IColumnReader | ||
{ | ||
internal static BinaryUnsignedInt8ColumnReader Instance { get; } = new BinaryUnsignedInt8ColumnReader(); | ||
|
||
public object ReadValue(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
return (byte) data[0]; | ||
} | ||
|
||
public int ReadInt32(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
return (int) (byte) data[0]; | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
src/MySqlConnector/ColumnReaders/BinaryYearColumnReader.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
namespace MySqlConnector.ColumnReaders; | ||
using System.Buffers.Text; | ||
using System.Runtime.InteropServices; | ||
using MySqlConnector.Protocol.Payloads; | ||
using MySqlConnector.Protocol.Serialization; | ||
using MySqlConnector.Utilities; | ||
|
||
internal sealed class BinaryYearColumnReader : IColumnReader | ||
{ | ||
internal static BinaryYearColumnReader Instance { get; } = new BinaryYearColumnReader(); | ||
|
||
public object ReadValue(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
return (int) MemoryMarshal.Read<short>(data); | ||
} | ||
|
||
public int ReadInt32(ReadOnlySpan<byte> data, ColumnDefinitionPayload columnDefinition) | ||
{ | ||
return (int) MemoryMarshal.Read<short>(data); | ||
} | ||
} |
Oops, something went wrong.