Skip to content

Commit

Permalink
Heap allocation optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
LTRData committed Dec 13, 2023
1 parent e2841b3 commit e312b55
Show file tree
Hide file tree
Showing 8 changed files with 297 additions and 224 deletions.
12 changes: 6 additions & 6 deletions Library/DiscUtils.Core/Partitions/BiosPartitionTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public override Guid DiskGuid

byte[] allocated = null;

var bootSector = _diskGeometry.BytesPerSector <= 512
var bootSector = _diskGeometry.BytesPerSector <= 1024
? stackalloc byte[_diskGeometry.BytesPerSector]
: (allocated = ArrayPool<byte>.Shared.Rent(_diskGeometry.BytesPerSector)).AsSpan(0, _diskGeometry.BytesPerSector);

Expand Down Expand Up @@ -257,7 +257,7 @@ public static BiosPartitionTable Initialize(Stream disk, Geometry diskGeometry)

byte[] allocated = null;

var bootSector = diskGeometry.BytesPerSector <= 512
var bootSector = diskGeometry.BytesPerSector <= 1024
? stackalloc byte[diskGeometry.BytesPerSector]
: (allocated = ArrayPool<byte>.Shared.Rent(diskGeometry.BytesPerSector)).AsSpan(0, diskGeometry.BytesPerSector);

Expand Down Expand Up @@ -571,7 +571,7 @@ public void UpdateBiosGeometry(Geometry geometry)

byte[] allocated = null;

var bootSector = _diskGeometry.BytesPerSector <= 512
var bootSector = _diskGeometry.BytesPerSector <= 1024
? stackalloc byte[_diskGeometry.BytesPerSector]
: (allocated = ArrayPool<byte>.Shared.Rent(_diskGeometry.BytesPerSector)).AsSpan(0, _diskGeometry.BytesPerSector);

Expand Down Expand Up @@ -701,7 +701,7 @@ private BiosPartitionRecord[] GetPrimaryRecords()

byte[] allocated = null;

var bootSector = _diskGeometry.BytesPerSector <= 512
var bootSector = _diskGeometry.BytesPerSector <= 1024
? stackalloc byte[_diskGeometry.BytesPerSector]
: (allocated = ArrayPool<byte>.Shared.Rent(_diskGeometry.BytesPerSector)).AsSpan(0, _diskGeometry.BytesPerSector);

Expand Down Expand Up @@ -731,7 +731,7 @@ private void WriteRecord(int i, BiosPartitionRecord newRecord)

byte[] allocated = null;

var bootSector = _diskGeometry.BytesPerSector <= 512
var bootSector = _diskGeometry.BytesPerSector <= 1024
? stackalloc byte[_diskGeometry.BytesPerSector]
: (allocated = ArrayPool<byte>.Shared.Rent(_diskGeometry.BytesPerSector)).AsSpan(0, _diskGeometry.BytesPerSector);

Expand Down Expand Up @@ -830,7 +830,7 @@ private void Init(Stream disk, Geometry diskGeometry)

byte[] allocated = null;

var bootSector = _diskGeometry.BytesPerSector <= 512
var bootSector = _diskGeometry.BytesPerSector <= 1024
? stackalloc byte[_diskGeometry.BytesPerSector]
: (allocated = ArrayPool<byte>.Shared.Rent(_diskGeometry.BytesPerSector)).AsSpan(0, _diskGeometry.BytesPerSector);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public BiosPartitionedDiskBuilder(VirtualDisk sourceDisk)

byte[] allocated = null;

var sector = _biosGeometry.BytesPerSector <= 512
var sector = _biosGeometry.BytesPerSector <= 1024
? stackalloc byte[_biosGeometry.BytesPerSector]
: (allocated = ArrayPool<byte>.Shared.Rent(_biosGeometry.BytesPerSector)).AsSpan(0, _biosGeometry.BytesPerSector);

Expand Down
29 changes: 21 additions & 8 deletions Library/DiscUtils.Ext/ExtentsFileBuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
//

using System;
using System.Buffers;
using System.Collections.Generic;
using System.IO;
using System.Threading;
Expand Down Expand Up @@ -455,17 +456,29 @@ public override void SetCapacity(long value)
private ExtentBlock LoadExtentBlock(ExtentIndex idxEntry)
{
uint blockSize = _context.SuperBlock.BlockSize;

_context.RawStream.Position = idxEntry.LeafPhysicalBlock * blockSize;


byte[] allocated = null;

var buffer = blockSize <= 1024
? stackalloc byte[(int)blockSize]
: new byte[blockSize];
: (allocated = ArrayPool<byte>.Shared.Rent((int)blockSize)).AsSpan(0, (int)blockSize);

try
{
_context.RawStream.ReadExactly(buffer);

var subBlock = EndianUtilities.ToStruct<ExtentBlock>(buffer);

_context.RawStream.ReadExactly(buffer);

ExtentBlock subBlock = EndianUtilities.ToStruct<ExtentBlock>(buffer);

return subBlock;
return subBlock;
}
finally
{
if (allocated is not null)
{
ArrayPool<byte>.Shared.Return(allocated);
}
}
}
}
43 changes: 20 additions & 23 deletions Library/DiscUtils.Ntfs/FixupRecordBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,23 +64,22 @@ public int UpdateSequenceSize

public void FromStream(Stream stream, int length, bool ignoreMagic = false)
{
if (length <= 1024)
byte[] allocated = null;

var buffer = length <= 1024
? stackalloc byte[length]
: (allocated = ArrayPool<byte>.Shared.Rent(length)).AsSpan(0, length);

try
{
Span<byte> buffer = stackalloc byte[length];
stream.ReadExactly(buffer);
FromBytes(buffer, ignoreMagic);
}
else
finally
{
var buffer = ArrayPool<byte>.Shared.Rent(length);
try
{
stream.ReadExactly(buffer, 0, length);
FromBytes(buffer.AsSpan(0, length), ignoreMagic);
}
finally
if (allocated is not null)
{
ArrayPool<byte>.Shared.Return(buffer);
ArrayPool<byte>.Shared.Return(allocated);
}
}
}
Expand Down Expand Up @@ -139,25 +138,23 @@ public void ToBytes(Span<byte> buffer)

public void ToStream(Stream stream, int length)
{
if (length <= 1024)
byte[] allocated = null;

var buffer = length <= 1024
? stackalloc byte[length]
: (allocated = ArrayPool<byte>.Shared.Rent(length)).AsSpan(0, length);

try
{
Span<byte> buffer = stackalloc byte[length];
buffer.Clear();
ToBytes(buffer);
stream.Write(buffer);
}
else
finally
{
var buffer = ArrayPool<byte>.Shared.Rent(length);
try
{
Array.Clear(buffer, 0, length);
ToBytes(buffer);
stream.Write(buffer, 0, length);
}
finally
if (allocated is not null)
{
ArrayPool<byte>.Shared.Return(buffer);
ArrayPool<byte>.Shared.Return(allocated);
}
}
}
Expand Down
19 changes: 16 additions & 3 deletions Library/DiscUtils.Ntfs/NtfsStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
//

using System;
using System.Buffers;
using System.Collections.Generic;
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -85,13 +86,25 @@ public byte[] GetContent()
public void SetContent<T>(T value)
where T : IByteArraySerializable, IDiagnosticTraceable, new()
{
byte[] allocated = null;

var buffer = value.Size <= 1024
? stackalloc byte[value.Size]
: new byte[value.Size];
: (allocated = ArrayPool<byte>.Shared.Rent(value.Size)).AsSpan(0, value.Size);

value.WriteTo(buffer);
try
{
value.WriteTo(buffer);

SetContent(buffer);
SetContent(buffer);
}
finally
{
if (allocated is not null)
{
ArrayPool<byte>.Shared.Return(allocated);
}
}
}

/// <summary>
Expand Down
Loading

0 comments on commit e312b55

Please sign in to comment.