DuckDB.NET icon indicating copy to clipboard operation
DuckDB.NET copied to clipboard

Making use of `LibraryImport` to reduce marshalling, smaller optimizations

Open kirides opened this issue 8 months ago • 3 comments

This project may benefit a lot from using LibraryImport-Attribute instead of DllImport (or combined with? idk if and how fallback would work)

As DuckDb is in Process, reducing the marshalling overhead by introducing LibraryImport may further increase throughput.

Side note: Things like StringVectorDataReader may also benefit from using string.Create(....) to reduce allocations to just a single "string", removing the additional new char[...] allocation.

Also DuckDB.NET.Data.Extensions.GuidConverter may benefit a lot from using Span<char> buffer = stackalloc char[36] to build the guid-representation in memory without allocating at all.

private static readonly char[] HexDigits = "0123456789abcdef".ToCharArray();
public static Guid ConvertToGuid_Optimized(DuckDB.NET.Native.DuckDBHugeInt input)
{
    Span<char> buffer = stackalloc char[32];
    long num = input.Upper ^ long.MinValue;
    int position = 0;
    ByteToHex(buffer, ref position, (ulong)((num >> 56) & 0xFF));
    ByteToHex(buffer, ref position, (ulong)((num >> 48) & 0xFF));
    ByteToHex(buffer, ref position, (ulong)((num >> 40) & 0xFF));
    ByteToHex(buffer, ref position, (ulong)((num >> 32) & 0xFF));
    //buffer[position++] = '-';
    ByteToHex(buffer, ref position, (ulong)((num >> 24) & 0xFF));
    ByteToHex(buffer, ref position, (ulong)((num >> 16) & 0xFF));
    //buffer[position++] = '-';
    ByteToHex(buffer, ref position, (ulong)((num >> 8) & 0xFF));
    ByteToHex(buffer, ref position, (ulong)(num & 0xFF));
    //buffer[position++] = '-';
    ByteToHex(buffer, ref position, (input.Lower >> 56) & 0xFF);
    ByteToHex(buffer, ref position, (input.Lower >> 48) & 0xFF);
    //buffer[position++] = '-';
    ByteToHex(buffer, ref position, (input.Lower >> 40) & 0xFF);
    ByteToHex(buffer, ref position, (input.Lower >> 32) & 0xFF);
    ByteToHex(buffer, ref position, (input.Lower >> 24) & 0xFF);
    ByteToHex(buffer, ref position, (input.Lower >> 16) & 0xFF);
    ByteToHex(buffer, ref position, (input.Lower >> 8) & 0xFF);
    ByteToHex(buffer, ref position, input.Lower & 0xFF);
    return Guid.ParseExact(buffer, "n");

    static void ByteToHex(Span<char> buffer, ref int position, ulong value)
    {
        buffer[position++] = HexDigits[(value >> 4) & 0xF];
        buffer[position++] = HexDigits[value & 0xF];
    }
}

kirides avatar Jun 11 '24 07:06 kirides