Skip to content

Commit

Permalink
Improve netstandard2.0 performance
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremy-visionaid committed Nov 20, 2024
1 parent bafb6c8 commit d146d09
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 55 deletions.
22 changes: 21 additions & 1 deletion OpenMcdf.Tests/StreamExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
namespace OpenMcdf.Tests;
#if !NET7_0_OR_GREATER
using System.Buffers;
#endif

namespace OpenMcdf.Tests;

internal static class StreamExtensions
{
#if !NET7_0_OR_GREATER
public static void ReadExactly(this Stream stream, Span<byte> buffer)
{
byte[] array = ArrayPool<byte>.Shared.Rent(buffer.Length);
try
{
stream.ReadExactly(array, 0, buffer.Length);
array.AsSpan(0, buffer.Length).CopyTo(buffer);
}
finally
{
ArrayPool<byte>.Shared.Return(array);
}
}
#endif

public static void Write(this Stream stream, byte[] buffer, WriteMode mode)
{
#if (!NETSTANDARD2_0 && !NETFRAMEWORK)
Expand Down
32 changes: 1 addition & 31 deletions OpenMcdf/CfbBinaryReader.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
using System.Diagnostics;
using System.Text;

#if NETSTANDARD2_0
using System.Buffers;
#endif

namespace OpenMcdf;

/// <summary>
Expand All @@ -26,37 +22,11 @@ public long Position
set => BaseStream.Position = value;
}

#if NETSTANDARD2_0

public int Read(Span<byte> buffer)
{
byte[] array = ArrayPool<byte>.Shared.Rent(buffer.Length);
try
{
int bytesRead = BaseStream.Read(array, 0, buffer.Length);
array.AsSpan(0, bytesRead).CopyTo(buffer);
return bytesRead;
}
finally
{
ArrayPool<byte>.Shared.Return(array);
}
}

#endif

void ReadExactly(byte[] buffer, int offset, int count) => BaseStream.ReadExactly(buffer, offset, count);

public Guid ReadGuid()
{
int bytesRead = 0;
do
{
int n = Read(guidBuffer, bytesRead, guidBuffer.Length - bytesRead);
if (n == 0)
throw new EndOfStreamException();
bytesRead += n;
} while (bytesRead < guidBuffer.Length);
BaseStream.ReadExactly(guidBuffer, 0, guidBuffer.Length);

return new Guid(guidBuffer);
}
Expand Down
2 changes: 1 addition & 1 deletion OpenMcdf/Fat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ void CacheCurrentSector()

CfbBinaryReader reader = Context.Reader;
reader.Position = current.Position;
reader.Read(cachedSectorBuffer);
reader.Read(cachedSectorBuffer, 0, cachedSectorBuffer.Length);
cachedSector = current;
}

Expand Down
12 changes: 6 additions & 6 deletions OpenMcdf/MiniFat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ internal sealed class MiniFat : ContextBase, IEnumerable<FatEntry>, IDisposable
{
private readonly FatChainEnumerator fatChainEnumerator;
private readonly int ElementsPerSector;
private readonly byte[] sector;
private readonly byte[] cachedSectorBuffer;
private bool isDirty;

public MiniFat(RootContextSite rootContextSite)
: base(rootContextSite)
{
ElementsPerSector = Context.SectorSize / sizeof(uint);
fatChainEnumerator = new(Context.Fat, Context.Header.FirstMiniFatSectorId);
sector = new byte[Context.SectorSize];
cachedSectorBuffer = new byte[Context.SectorSize];
}

public void Dispose()
Expand All @@ -36,7 +36,7 @@ public void Flush()
{
CfbBinaryWriter writer = Context.Writer;
writer.Position = fatChainEnumerator.CurrentSector.Position;
writer.Write(sector);
writer.Write(cachedSectorBuffer);
isDirty = false;
}
}
Expand Down Expand Up @@ -74,7 +74,7 @@ bool TryMoveToSectorForKey(uint key, out long elementIndex)

CfbBinaryReader reader = Context.Reader;
reader.Position = fatChainEnumerator.CurrentSector.Position;
reader.Read(sector);
reader.Read(cachedSectorBuffer, 0, cachedSectorBuffer.Length);
return true;
}

Expand All @@ -88,7 +88,7 @@ public bool TryGetValue(uint key, out uint value)
return false;
}

Span<byte> slice = sector.AsSpan((int)elementIndex * sizeof(uint));
Span<byte> slice = cachedSectorBuffer.AsSpan((int)elementIndex * sizeof(uint));
value = BinaryPrimitives.ReadUInt32LittleEndian(slice);
return true;
}
Expand All @@ -100,7 +100,7 @@ public bool TrySetValue(uint key, uint value)
if (!TryMoveToSectorForKey(key, out long elementIndex))
return false;

Span<byte> slice = sector.AsSpan((int)elementIndex * sizeof(uint));
Span<byte> slice = cachedSectorBuffer.AsSpan((int)elementIndex * sizeof(uint));
BinaryPrimitives.WriteUInt32LittleEndian(slice, value);
isDirty = true;
return true;
Expand Down
14 changes: 0 additions & 14 deletions OpenMcdf/StreamExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,6 @@ internal static class StreamExtensions
{
#if !NET7_0_OR_GREATER

public static void ReadExactly(this Stream stream, Span<byte> buffer)
{
byte[] array = ArrayPool<byte>.Shared.Rent(buffer.Length);
try
{
stream.ReadExactly(array, 0, buffer.Length);
array.AsSpan(0, buffer.Length).CopyTo(buffer);
}
finally
{
ArrayPool<byte>.Shared.Return(array);
}
}

public static void ReadExactly(this Stream stream, byte[] buffer, int offset, int count)
{
if (count == 0)
Expand Down
4 changes: 2 additions & 2 deletions OpenMcdf/TransactedStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public override void Write(byte[] buffer, int offset, int count)
{
// Copy the existing sector data
originalStream.Position = originalPosition - sectorOffset;
originalStream.ReadExactly(this.buffer);
originalStream.ReadExactly(this.buffer, 0, this.buffer.Length);

OverlayStream.Position = overlayPosition;
OverlayStream.Write(this.buffer, 0, this.buffer.Length);
Expand All @@ -122,7 +122,7 @@ public void Commit()
foreach (KeyValuePair<uint, long> entry in dirtySectorPositions)
{
OverlayStream.Position = entry.Value;
OverlayStream.ReadExactly(buffer);
OverlayStream.ReadExactly(buffer, 0, buffer.Length);

originalStream.Position = entry.Key * Context.SectorSize;
originalStream.Write(buffer, 0, buffer.Length);
Expand Down

0 comments on commit d146d09

Please sign in to comment.