Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance: Uses ReadOnlySpan #131

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ $baseDir = Split-Path -Parent $PSCommandPath
$outDir = "$baseDir\out"
$versionProvider = ''
$versionEFCore = ''
$versionEF6 = ''

function Clean() {
if (Test-Path $outDir) {
Expand Down Expand Up @@ -39,17 +38,14 @@ function Versions() {
}
$script:versionProvider = v $baseDir\src\FirebirdSql.Data.FirebirdClient\bin\$Configuration\net8.0\FirebirdSql.Data.FirebirdClient.dll
$script:versionEFCore = v $baseDir\src\FirebirdSql.EntityFrameworkCore.Firebird\bin\$Configuration\net8.0\FirebirdSql.EntityFrameworkCore.Firebird.dll
$script:versionEF6 = v $baseDir\src\EntityFramework.Firebird\bin\$Configuration\net48\EntityFramework.Firebird.dll
}

function NuGets() {
cp $baseDir\src\FirebirdSql.Data.FirebirdClient\bin\$Configuration\FirebirdSql.Data.FirebirdClient.$versionProvider.nupkg $outDir
cp $baseDir\src\FirebirdSql.EntityFrameworkCore.Firebird\bin\$Configuration\FirebirdSql.EntityFrameworkCore.Firebird.$versionEFCore.nupkg $outDir
cp $baseDir\src\EntityFramework.Firebird\bin\$Configuration\EntityFramework.Firebird.$versionEF6.nupkg $outDir

cp $baseDir\src\FirebirdSql.Data.FirebirdClient\bin\$Configuration\FirebirdSql.Data.FirebirdClient.$versionProvider.snupkg $outDir
cp $baseDir\src\FirebirdSql.EntityFrameworkCore.Firebird\bin\$Configuration\FirebirdSql.EntityFrameworkCore.Firebird.$versionEFCore.snupkg $outDir
cp $baseDir\src\EntityFramework.Firebird\bin\$Configuration\EntityFramework.Firebird.$versionEF6.snupkg $outDir
}

Clean
Expand Down
6 changes: 1 addition & 5 deletions src/EntityFramework.Firebird/EntityFramework.Firebird.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net48;netstandard2.1</TargetFrameworks>
<TargetFrameworks>netstandard2.1</TargetFrameworks>
<AssemblyName>EntityFramework.Firebird</AssemblyName>
<RootNamespace>EntityFramework.Firebird</RootNamespace>
<SignAssembly>true</SignAssembly>
Expand Down Expand Up @@ -48,10 +48,6 @@
<ItemGroup>
<PackageReference Include="EntityFramework" Version="$(EF6ReferencePackageVersion)" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'=='net48'">
<Reference Include="System.Configuration" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'=='netstandard2.1'">
</ItemGroup>
<ItemGroup Condition="'$(Configuration)'!='Debug'">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

//$Authors = Jiri Cincura ([email protected])

using System;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading;
Expand Down Expand Up @@ -42,11 +43,24 @@ public ValueTask<int> ReadAsync(byte[] buffer, int offset, int count, Cancellati
return new ValueTask<int>(_stream.ReadAsync(buffer, offset, count, cancellationToken));
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(ReadOnlySpan<byte> buffer)
{
_stream.Write(buffer);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(byte[] buffer, int offset, int count)
{
_stream.Write(buffer, offset, count);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public async ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default)
{
await _stream.WriteAsync(buffer, cancellationToken).ConfigureAwait(false);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ValueTask WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken = default)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ sealed class FirebirdNetworkHandlingWrapper : IDataProvider, ITracksIOFailure

readonly IDataProvider _dataProvider;

readonly Queue<byte> _outputBuffer;
readonly MemoryStream _outputBuffer;
readonly Queue<byte> _inputBuffer;
readonly byte[] _readBuffer;

Expand All @@ -48,7 +48,7 @@ public FirebirdNetworkHandlingWrapper(IDataProvider dataProvider)
{
_dataProvider = dataProvider;

_outputBuffer = new Queue<byte>(PreferredBufferSize);
_outputBuffer = new MemoryStream(PreferredBufferSize);
_inputBuffer = new Queue<byte>(PreferredBufferSize);
_readBuffer = new byte[PreferredBufferSize];
}
Expand Down Expand Up @@ -120,22 +120,31 @@ public async ValueTask<int> ReadAsync(byte[] buffer, int offset, int count, Canc
return dataLength;
}

public void Write(ReadOnlySpan<byte> buffer)
{
_outputBuffer.Write(buffer);
}

public void Write(byte[] buffer, int offset, int count)
{
for (var i = offset; i < count; i++)
_outputBuffer.Enqueue(buffer[offset + i]);
_outputBuffer.Write(buffer, offset, count);
}

public async ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default)
{
await _outputBuffer.WriteAsync(buffer, cancellationToken).ConfigureAwait(false);
}

public ValueTask WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken = default)
{
for (var i = offset; i < count; i++)
_outputBuffer.Enqueue(buffer[offset + i]);
_outputBuffer.Write(buffer, offset, count);
return ValueTask2.CompletedTask;
}

public void Flush()
{
var buffer = _outputBuffer.ToArray();
_outputBuffer.Clear();
_outputBuffer.SetLength(0);
var count = buffer.Length;
if (_compressor != null)
{
Expand All @@ -160,7 +169,7 @@ public void Flush()
public async ValueTask FlushAsync(CancellationToken cancellationToken = default)
{
var buffer = _outputBuffer.ToArray();
_outputBuffer.Clear();
_outputBuffer.SetLength(0);
var count = buffer.Length;
if (_compressor != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

//$Authors = Jiri Cincura ([email protected])

using System;
using System.Threading;
using System.Threading.Tasks;

Expand All @@ -25,7 +26,10 @@ interface IDataProvider
int Read(byte[] buffer, int offset, int count);
ValueTask<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken = default);

void Write(ReadOnlySpan<byte> buffer);
void Write(byte[] buffer, int offset, int count);

ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default);
ValueTask WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken = default);

void Flush();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ public override DbValue[] Fetch()
{
_database.Xdr.Write(IscCodes.op_fetch);
_database.Xdr.Write(_handle);
_database.Xdr.WriteBuffer(_fields.ToBlr().Data);
_database.Xdr.WriteBuffer(_fields.ToBlrSpan());
_database.Xdr.Write(0); // p_sqldata_message_number
_database.Xdr.Write(_fetchSize); // p_sqldata_messages
_database.Xdr.Flush();
Expand Down Expand Up @@ -480,7 +480,7 @@ public override async ValueTask<DbValue[]> FetchAsync(CancellationToken cancella
{
await _database.Xdr.WriteAsync(IscCodes.op_fetch, cancellationToken).ConfigureAwait(false);
await _database.Xdr.WriteAsync(_handle, cancellationToken).ConfigureAwait(false);
await _database.Xdr.WriteBufferAsync(_fields.ToBlr().Data, cancellationToken).ConfigureAwait(false);
await _database.Xdr.WriteBufferAsync(_fields.ToBlrMemory(), cancellationToken).ConfigureAwait(false);
await _database.Xdr.WriteAsync(0, cancellationToken).ConfigureAwait(false); // p_sqldata_message_number
await _database.Xdr.WriteAsync(_fetchSize, cancellationToken).ConfigureAwait(false); // p_sqldata_messages
await _database.Xdr.FlushAsync(cancellationToken).ConfigureAwait(false);
Expand Down Expand Up @@ -781,7 +781,7 @@ protected virtual void SendExecuteToBuffer(int timeout, IDescriptorFiller descri

if (_parameters != null)
{
_database.Xdr.WriteBuffer(_parameters.ToBlr().Data);
_database.Xdr.WriteBuffer(_parameters.ToBlrSpan());
_database.Xdr.Write(0); // Message number
_database.Xdr.Write(1); // Number of messages
_database.Xdr.WriteBytes(parametersData, parametersData.Length);
Expand All @@ -795,7 +795,12 @@ protected virtual void SendExecuteToBuffer(int timeout, IDescriptorFiller descri

if (StatementType == DbStatementType.StoredProcedure)
{
_database.Xdr.WriteBuffer(_fields?.ToBlr().Data);
_database.Xdr.WriteBuffer(
_fields is null
? ReadOnlySpan<byte>.Empty
: _fields.ToBlrSpan()
);

_database.Xdr.Write(0); // Output message number
}
}
Expand All @@ -818,7 +823,7 @@ protected virtual async ValueTask SendExecuteToBufferAsync(int timeout, IDescrip

if (_parameters != null)
{
await _database.Xdr.WriteBufferAsync(_parameters.ToBlr().Data, cancellationToken).ConfigureAwait(false);
await _database.Xdr.WriteBufferAsync(_parameters.ToBlrMemory(), cancellationToken).ConfigureAwait(false);
await _database.Xdr.WriteAsync(0, cancellationToken).ConfigureAwait(false); // Message number
await _database.Xdr.WriteAsync(1, cancellationToken).ConfigureAwait(false); // Number of messages
await _database.Xdr.WriteBytesAsync(parametersData, parametersData.Length, cancellationToken).ConfigureAwait(false);
Expand All @@ -832,7 +837,12 @@ protected virtual async ValueTask SendExecuteToBufferAsync(int timeout, IDescrip

if (StatementType == DbStatementType.StoredProcedure)
{
await _database.Xdr.WriteBufferAsync(_fields?.ToBlr().Data, cancellationToken).ConfigureAwait(false);
await _database.Xdr.WriteBufferAsync(
_fields is null
? ReadOnlyMemory<byte>.Empty
: _fields.ToBlrMemory(),
cancellationToken
).ConfigureAwait(false);
await _database.Xdr.WriteAsync(0, cancellationToken).ConfigureAwait(false); // Output message number
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ public override ExecuteResultItem[] Execute(int count, IDescriptorFiller descrip

Database.Xdr.Write(IscCodes.op_batch_create);
Database.Xdr.Write(_statement.Handle); // p_batch_statement
var blr = _statement.Parameters.ToBlr();
Database.Xdr.WriteBuffer(blr.Data); // p_batch_blr
Database.Xdr.Write(blr.Length); // p_batch_msglen
var blr = _statement.Parameters.ToBlrSpan(out var blrMsgLen);
Database.Xdr.WriteBuffer(blr); // p_batch_blr
Database.Xdr.Write(blrMsgLen); // p_batch_msglen
var pb = _statement.CreateBatchParameterBuffer();
if (_statement.ReturnRecordsAffected)
{
Expand Down Expand Up @@ -96,9 +96,9 @@ public override async ValueTask<ExecuteResultItem[]> ExecuteAsync(int count, IDe

await Database.Xdr.WriteAsync(IscCodes.op_batch_create, cancellationToken).ConfigureAwait(false);
await Database.Xdr.WriteAsync(_statement.Handle, cancellationToken).ConfigureAwait(false); // p_batch_statement
var blr = _statement.Parameters.ToBlr();
await Database.Xdr.WriteBufferAsync(blr.Data, cancellationToken).ConfigureAwait(false); // p_batch_blr
await Database.Xdr.WriteAsync(blr.Length, cancellationToken).ConfigureAwait(false); // p_batch_msglen
var blr = _statement.Parameters.ToBlrMemory(out var blrMsgLen);
await Database.Xdr.WriteBufferAsync(blr, cancellationToken).ConfigureAwait(false); // p_batch_blr
await Database.Xdr.WriteAsync(blrMsgLen, cancellationToken).ConfigureAwait(false); // p_batch_msglen
var pb = _statement.CreateBatchParameterBuffer();
if (_statement.ReturnRecordsAffected)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -521,11 +521,22 @@ public void WriteBuffer(byte[] buffer)
{
WriteBuffer(buffer, buffer?.Length ?? 0);
}

public ValueTask WriteBufferAsync(byte[] buffer, CancellationToken cancellationToken = default)
{
return WriteBufferAsync(buffer, buffer?.Length ?? 0, cancellationToken);
}

public void WriteBuffer(ReadOnlySpan<byte> buffer)
{
Write(buffer.Length);
if (buffer.Length > 0)
{
_dataProvider.Write(buffer);
WritePad((4 - buffer.Length) & 3);
}
}

public void WriteBuffer(byte[] buffer, int length)
{
Write(length);
Expand All @@ -535,6 +546,17 @@ public void WriteBuffer(byte[] buffer, int length)
WritePad((4 - length) & 3);
}
}

public async Task WriteBufferAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken)
{
await WriteAsync(buffer.Length, cancellationToken).ConfigureAwait(false);
if (buffer.Length > 0)
{
await _dataProvider.WriteAsync(buffer, cancellationToken).ConfigureAwait(false);
await WritePadAsync((4 - buffer.Length) & 3, cancellationToken).ConfigureAwait(false);
}
}

public async ValueTask WriteBufferAsync(byte[] buffer, int length, CancellationToken cancellationToken = default)
{
await WriteAsync(length, cancellationToken).ConfigureAwait(false);
Expand Down Expand Up @@ -838,6 +860,5 @@ ValueTask WriteFillAsync(int length, CancellationToken cancellationToken = defau
{
return _dataProvider.WriteAsync(FillArray, 0, length, cancellationToken);
}

#endregion
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,12 @@

//$Authors = Carlos Guzman Alvarez, Jiri Cincura ([email protected])

using System.Runtime.InteropServices;

namespace FirebirdSql.Data.Client.Native.Marshalers;

[StructLayout(LayoutKind.Sequential)]
internal struct XSQLDA
internal unsafe struct XSQLDA_STRUCT
{
public short version;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public string sqldaid;
public fixed byte sqldaid[8];
public int sqldabc;
public short sqln;
public short sqld;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,10 @@
//$Authors = Carlos Guzman Alvarez, Jiri Cincura ([email protected])

using System;
using System.Runtime.InteropServices;

namespace FirebirdSql.Data.Client.Native.Marshalers;

[StructLayout(LayoutKind.Sequential)]
internal class XSQLVAR
internal unsafe struct XSQLVAR_STRUCT
{
public short sqltype;
public short sqlscale;
Expand All @@ -30,15 +28,11 @@ internal class XSQLVAR
public IntPtr sqldata;
public IntPtr sqlind;
public short sqlname_length;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] sqlname;
public fixed byte sqlname[32];
public short relname_length;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] relname;
public fixed byte relname[32];
public short ownername_length;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] ownername;
public fixed byte ownername[32];
public short aliasname_length;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] aliasname;
public fixed byte aliasname[32];
}
Loading
Loading