Skip to content

Commit 206c336

Browse files
Minor cleanup and massive memory improvements (#39)
* Cleaned up some code and improved perf Perf: 116 ms -> 99 ms Memory: 1.32 GB -> 32 MB * Update EndianReader.cs
1 parent 6af7c75 commit 206c336

File tree

5 files changed

+34
-37
lines changed

5 files changed

+34
-37
lines changed

CpkTools/Endian/EndianReader.cs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Buffers;
12
using System.Buffers.Binary;
23
using CommunityToolkit.HighPerformance;
34

@@ -147,20 +148,25 @@ public int ReadStreamInto(Stream dest, int length) {
147148
return 0;
148149
}
149150

150-
var buffer = new byte[80 * 1024];
151+
var buffer = ArrayPool<byte>.Shared.Rent(80 * 1024);
151152
var remaining = length;
152153
var totalRead = 0;
153154

154-
while (remaining > 0) {
155-
var toRead = Math.Min(buffer.Length, remaining);
156-
var read = BaseStream.Read(buffer, 0, toRead);
155+
try {
156+
while (remaining > 0) {
157+
var toRead = Math.Min(buffer.Length, remaining);
158+
var read = BaseStream.Read(buffer, 0, toRead);
157159

158-
if (read == 0) // EOF
159-
break;
160+
if (read == 0) // EOF
161+
break;
160162

161-
dest.Write(buffer, 0, read);
162-
totalRead += read;
163-
remaining -= read;
163+
dest.Write(buffer, 0, read);
164+
totalRead += read;
165+
remaining -= read;
166+
}
167+
}
168+
finally {
169+
ArrayPool<byte>.Shared.Return(buffer);
164170
}
165171

166172
return totalRead;

CpkTools/Model/Cpk.cs

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System.Buffers.Binary;
21
using System.Numerics;
32
using System.Text;
43
using CpkTools.Comparers;
@@ -61,14 +60,6 @@ public bool ReadCpk(string path) {
6160
return false;
6261
}
6362

64-
/*try {
65-
for (var i = 0; i < _utf.Columns.Count; i++) {
66-
_cpkData.Add(_utf.Columns[i].Name, _utf.Rows[0][i].GetValue()!);
67-
}
68-
} catch (Exception ex) {
69-
Console.WriteLine(ex);
70-
}*/
71-
7263
ContentOffset = TryGetColumnData<ulong>(_utf, 0, "ContentOffset", out var content) ? content.Value : ulong.MaxValue;
7364

7465
var newEntry = CreateFileEntry("CONTENT_OFFSET", ContentOffset, content.Position, "CPK", "CONTENT", false);
@@ -273,7 +264,7 @@ public void WriteGtoc(EndianWriter writer) {
273264
}
274265

275266
private static void WritePacket(EndianWriter writer, string id, ulong position, Memory<byte> packet) {
276-
if (position == 0xffffffffffffffff)
267+
if (position == ulong.MaxValue)
277268
return;
278269

279270
writer.Seek((long)position, SeekOrigin.Begin);
@@ -576,17 +567,14 @@ private static bool TryGetColumnData<T>(Utf utf, int rowIndex, string columnName
576567

577568
private static ColumnData<T> GetColumnData<T>(Utf utf, int rowIndex, string columnName) {
578569
try {
579-
var columnIndex = utf.Columns!.FindIndex(c => c.Name == columnName);
580-
581-
if (columnIndex == -1) {
570+
if (!utf.ColumnIndex!.TryGetValue(columnName, out var columnIndex))
582571
return new ColumnData<T>(default!, -1, null);
583-
}
584572

585573
var row = utf.Rows![rowIndex][columnIndex];
586574

587575
var cell = row.GetValue();
588576
var position = row.Position;
589-
var type = row.GetType();
577+
var type = row.GetValueType();
590578

591579
if (cell is T value)
592580
return new ColumnData<T>(value, position, type);

CpkTools/Model/Row.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public record struct Row() {
2525
};
2626
}
2727

28-
public new Type? GetType() {
28+
public Type? GetValueType() {
2929
return Type switch {
3030
0 or 1 => UInt8.GetType(),
3131
2 or 3 => UInt16.GetType(),

CpkTools/Model/Utf.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
namespace CpkTools.Model;
44

55
public class Utf {
6-
public List<Column>? Columns { get; private set; }
6+
public Dictionary<string, int>? ColumnIndex { get; private set; }
7+
public Column[]? Columns { get; private set; }
78
public Row[][]? Rows { get; private set; }
89

910
private int _tableSize;
@@ -16,19 +17,19 @@ public class Utf {
1617
private int _numRows;
1718

1819
public bool ReadUtf(Memory<byte> data) {
19-
var reader = new EndianReader(data);
20+
using var reader = new EndianReader(data);
2021

2122
return ReadUtf(reader);
2223
}
2324

2425
public bool ReadUtf(byte[] data) {
25-
var reader = new EndianReader(data);
26+
using var reader = new EndianReader(data);
2627

2728
return ReadUtf(reader);
2829
}
2930

3031
public bool ReadUtf(Stream stream) {
31-
var reader = new EndianReader(stream);
32+
using var reader = new EndianReader(stream);
3233

3334
return ReadUtf(reader);
3435
}
@@ -54,9 +55,11 @@ private bool ReadUtf(EndianReader reader, bool leaveOpen = false) {
5455
_rowLength = reader.ReadInt16();
5556
_numRows = reader.ReadInt32();
5657

57-
Columns = new List<Column>(_numColumns);
58+
Columns = new Column[_numColumns];
5859
Rows = new Row[_numRows][];
5960

61+
ColumnIndex = new Dictionary<string, int>(_numColumns, StringComparer.Ordinal);
62+
6063
// Read Columns
6164
for (var i = 0; i < _numColumns; i ++) {
6265
var column = new Column {
@@ -69,7 +72,9 @@ private bool ReadUtf(EndianReader reader, bool leaveOpen = false) {
6972
}
7073

7174
column.Name = Tools.ReadCString(reader, -1, reader.ReadInt32() + _stringsOffset);
72-
Columns.Add(column);
75+
Columns[i] = column;
76+
77+
ColumnIndex[column.Name] = i;
7378
}
7479

7580
const int storageMask = (int)StorageFlags.StorageMask;

CpkTools/Tools.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@
44
namespace CpkTools;
55

66
public static class Tools {
7+
private static readonly Encoding SjisEncoding;
8+
79
static Tools() {
810
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
11+
SjisEncoding = Encoding.GetEncoding(932);
912
}
1013

1114
public static string ReadCString(EndianReader reader, int maxLength = -1, long lOffset = -1, Encoding? enc = null) {
12-
enc ??= Encoding.GetEncoding(932);
15+
enc ??= SjisEncoding;
1316

1417
var max = maxLength == -1 ? 255 : maxLength;
1518
var fTemp = reader.Position;
@@ -41,11 +44,6 @@ public static string ReadCString(EndianReader reader, int maxLength = -1, long l
4144
return enc.GetString(bytes);
4245
}
4346

44-
public static void DeleteFileIfExists(string sPath) {
45-
if (File.Exists(sPath))
46-
File.Delete(sPath);
47-
}
48-
4947
public static string GetPath(string input) {
5048
return Path.GetDirectoryName(input) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(input);
5149
}

0 commit comments

Comments
 (0)