Skip to content

Commit 7f76369

Browse files
committed
针对大照片下,减少LOH对象的创建,经过修改,同一张NIKON Z8拍摄的无压缩照片(56.3 MB (59,137,944 字节))由之前的读取一次创建80MB的LOH对象减少到读取一次只创建16MB的LOH对象。目前仅在net8编译。
1 parent db88000 commit 7f76369

File tree

1 file changed

+53
-23
lines changed

1 file changed

+53
-23
lines changed

src/Magick.NET/Helpers/ByteArrayWrapper.cs

Lines changed: 53 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,45 @@
22
// Licensed under the Apache License, Version 2.0.
33

44
using System;
5+
using System.Buffers;
56
using System.IO;
67

78
namespace ImageMagick;
89

9-
internal sealed unsafe class ByteArrayWrapper
10-
{
11-
private byte[] _bytes = new byte[8192];
12-
private int _offset = 0;
13-
private int _length = 0;
10+
internal sealed unsafe class ByteArrayWrapper {
11+
private static readonly ArrayPool<byte> _pool = ArrayPool<byte>.Create(1024 * 1024 * 64, 1024);
12+
private byte[] _bytes = _pool.Rent(1024 * 1024);
13+
private int _length;
14+
private int _offset;
1415

1516
public byte[] GetBytes()
1617
{
17-
ResizeBytes(_length);
18-
return _bytes;
18+
var result = new byte[_length];
19+
Array.Copy(_bytes, result, Math.Min(_bytes.Length, _length));
20+
_pool.Return(_bytes, true);
21+
return result;
1922
}
2023

2124
public long Read(IntPtr data, UIntPtr count, IntPtr user_data)
2225
{
2326
if (data == IntPtr.Zero)
27+
{
2428
return 0;
29+
}
30+
31+
int total = (int) count;
2532

26-
var total = (int)count;
2733
if (total == 0)
34+
{
2835
return 0;
36+
}
37+
38+
int length = Math.Min(total, _length - _offset);
2939

30-
var length = Math.Min(total, _length - _offset);
3140
if (length != 0)
3241
{
33-
var destination = (byte*)data.ToPointer();
42+
byte* destination = (byte*) data.ToPointer();
43+
3444
fixed (byte* source = _bytes)
3545
{
3646
NativeMemory.Copy(source + _offset, destination, length);
@@ -44,43 +54,54 @@ public long Read(IntPtr data, UIntPtr count, IntPtr user_data)
4454

4555
public long Seek(long offset, IntPtr whence, IntPtr user_data)
4656
{
47-
var newOffset = (int)((SeekOrigin)whence switch
48-
{
49-
SeekOrigin.Begin => offset,
50-
SeekOrigin.Current => _offset + offset,
51-
SeekOrigin.End => _length - offset,
52-
_ => -1,
53-
});
57+
int newOffset = (int) ((SeekOrigin) whence switch
58+
{
59+
SeekOrigin.Begin => offset,
60+
SeekOrigin.Current => _offset + offset,
61+
SeekOrigin.End => _length - offset,
62+
_ => -1
63+
});
5464

5565
if (_offset == newOffset)
66+
{
5667
return _offset;
68+
}
5769

5870
if (newOffset < 0)
71+
{
5972
return -1;
73+
}
6074

6175
_offset = newOffset;
6276

6377
return _offset;
6478
}
6579

6680
public long Tell(IntPtr user_data)
67-
=> _offset;
81+
{
82+
return _offset;
83+
}
6884

6985
public long Write(IntPtr data, UIntPtr count, IntPtr user_data)
7086
{
7187
if (data == IntPtr.Zero)
88+
{
7289
return 0;
90+
}
7391

74-
var total = (int)count;
92+
int total = (int) count;
7593

7694
if (total == 0)
95+
{
7796
return 0;
97+
}
7898

79-
var newOffset = _offset + total;
99+
int newOffset = _offset + total;
80100

81101
EnsureLength(newOffset);
82102

83-
var source = (byte*)data.ToPointer();
103+
byte* source = (byte*) data.ToPointer();
104+
84105
fixed (byte* destination = _bytes)
85106
{
86107
NativeMemory.Copy(source, destination + _offset, total);
@@ -94,17 +115,26 @@ public long Write(IntPtr data, UIntPtr count, IntPtr user_data)
94115
private void EnsureLength(int length)
95116
{
96117
if (length < _length)
118+
{
97119
return;
120+
}
98121

99122
_length = length;
100123

101124
if (_length < _bytes.Length)
125+
{
102126
return;
127+
}
103128

104-
var newLength = Math.Max(_bytes.Length * 2, _length);
129+
int newLength = Math.Max(_bytes.Length * 2, _length);
105130
ResizeBytes(newLength);
106131
}
107132

108133
private void ResizeBytes(int length)
109-
=> Array.Resize(ref _bytes, length);
134+
{
135+
byte[] byte2 = _pool.Rent(length);
136+
Array.Copy(_bytes, byte2, Math.Min(_bytes.Length, length));
137+
_pool.Return(_bytes, true);
138+
_bytes = byte2;
139+
}
110140
}

0 commit comments

Comments
 (0)