diff --git a/SharpCompress/Archives/SevenZip/SevenZipArchiveEntry.cs b/SharpCompress/Archives/SevenZip/SevenZipArchiveEntry.cs index c22c06ec4..6adb45a76 100644 --- a/SharpCompress/Archives/SevenZip/SevenZipArchiveEntry.cs +++ b/SharpCompress/Archives/SevenZip/SevenZipArchiveEntry.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.CompilerServices; namespace SharpCompress.Archives.SevenZip; @@ -38,6 +39,7 @@ public DateTime? LastModifiedTime public bool IsDirectory; + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void Reset() { HasStream = true; diff --git a/SharpCompress/Common/SevenZip/ArchiveDatabase.cs b/SharpCompress/Common/SevenZip/ArchiveDatabase.cs index ca5d224e0..66207de3b 100644 --- a/SharpCompress/Common/SevenZip/ArchiveDatabase.cs +++ b/SharpCompress/Common/SevenZip/ArchiveDatabase.cs @@ -1,7 +1,7 @@ #nullable disable using System; -using System.Collections.Generic; +using System.Runtime.CompilerServices; using SharpCompress.Archives.SevenZip; using static AL_Common.Common; @@ -13,17 +13,18 @@ internal sealed class ArchiveDatabase internal byte _minorVersion; internal long _startPositionAfterHeader; - internal readonly List _folders = new(); + internal readonly ListFast _folders = new(0); internal readonly ListFast _numUnpackStreamsVector = new(0); internal readonly ListFast _files = new(0); + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void Clear() { _majorVersion = 0; _minorVersion = 0; _startPositionAfterHeader = 0; - _folders.Clear(); + _folders.ClearFast(); _numUnpackStreamsVector.ClearFast(); _files.ClearFast(); } diff --git a/SharpCompress/Common/SevenZip/ArchiveReader.cs b/SharpCompress/Common/SevenZip/ArchiveReader.cs index 911eec2a9..9078b6cee 100644 --- a/SharpCompress/Common/SevenZip/ArchiveReader.cs +++ b/SharpCompress/Common/SevenZip/ArchiveReader.cs @@ -261,7 +261,7 @@ private void ReadAttributeVector( private void GetNextFolderItem(CFolder folder) { int numCoders = ReadNum(); - folder._coders = new List(numCoders); + folder._coders.ClearAndEnsureCapacity(numCoders); int numInStreams = 0; int numOutStreams = 0; for (int i = 0; i < numCoders; i++) @@ -319,7 +319,7 @@ private void GetNextFolderItem(CFolder folder) } int numBindPairs = numOutStreams - 1; - folder._bindPairs = new List(numBindPairs); + folder._bindPairs.ClearAndEnsureCapacity(numBindPairs); for (int i = 0; i < numBindPairs; i++) { var bp = new CBindPair @@ -419,12 +419,21 @@ private void ReadUnpackInfo(List dataVector) { streamSwitch.Set(this, dataVector); - db._folders.ClearAndEnsureCapacity(numFolders); + db._folders.SetRecycleState(numFolders, 25_000); for (int i = 0; i < numFolders; i++) { - var f = new CFolder(); - db._folders.Add(f); - GetNextFolderItem(f); + CFolder folder = db._folders[i]; + if (folder != null) + { + folder.Reset(); + } + else + { + folder = new CFolder(); + db._folders[i] = folder; + } + + GetNextFolderItem(folder); } } @@ -609,8 +618,10 @@ out _ var dataVector = new List(db._folders.Count); const int packIndex = 0; - foreach (CFolder folder in db._folders) + for (int folderIndex = 0; folderIndex < db._folders.Count; folderIndex++) { + CFolder folder = db._folders[folderIndex]; + long oldDataStartPos = dataStartPos; int myPackSizesLength = folder._packStreams.Count; long[] myPackSizes = _context.LongArrayPool.Rent(myPackSizesLength); diff --git a/SharpCompress/Common/SevenZip/CFolder.cs b/SharpCompress/Common/SevenZip/CFolder.cs index cf47098a9..7e33f6898 100644 --- a/SharpCompress/Common/SevenZip/CFolder.cs +++ b/SharpCompress/Common/SevenZip/CFolder.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Runtime.CompilerServices; using AL_Common; using SharpCompress.Archives.SevenZip; using SharpCompress.Compressors.LZMA; @@ -8,14 +9,24 @@ namespace SharpCompress.Common.SevenZip; internal sealed class CFolder { - internal List _coders = new(); - internal List _bindPairs = new(); + internal readonly List _coders = new(); + internal readonly List _bindPairs = new(); internal readonly List _packStreams = new(); internal readonly List _unpackSizes = new(); internal uint? _unpackCrc; internal bool UnpackCrcDefined => _unpackCrc != null; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal void Reset() + { + _coders.Clear(); + _bindPairs.Clear(); + _packStreams.Clear(); + _unpackSizes.Clear(); + _unpackCrc = null; + } + public long GetUnpackSize() { if (_unpackSizes.Count == 0)