From 33a91cbc5d649ce09d2dafb98072fe110666f8a8 Mon Sep 17 00:00:00 2001 From: Callan Barrett Date: Wed, 10 Dec 2025 17:07:38 +0800 Subject: [PATCH] perf: optimize SNES identifier to read only ~66KB instead of full file The SNES identifier was reading the entire ROM file (256KB-6MB) when it only needs to read up to the HiROM header location (0xFFC0 + 32 bytes). Changes: - Detect SMC header presence by checking file size (size % 1024 == 512) - Calculate read offset to skip SMC header if present - Only read up to ~66KB max instead of the full file This provides approximately 100x reduction in I/O for SNES files while maintaining identical ID generation, matching the original Python GameID behavior. --- identifier/snes.go | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/identifier/snes.go b/identifier/snes.go index 2efa0c6..1a24537 100644 --- a/identifier/snes.go +++ b/identifier/snes.go @@ -156,15 +156,23 @@ func snesGetHardware(romType, mapMode byte, data []byte, headerStart int) string // Identify extracts SNES game information from the given reader. func (*SNESIdentifier) Identify(reader io.ReaderAt, size int64, db Database) (*Result, error) { - // Read entire ROM for analysis - data := make([]byte, size) - if _, err := reader.ReadAt(data, 0); err != nil && err != io.EOF { - return nil, fmt.Errorf("failed to read SNES ROM: %w", err) + // Determine if file has SMC header (512 bytes) by checking file size + hasSMCHeader := size%1024 == 512 + + // Calculate read offset and size - we only need to read up to the HiROM header location + // plus header size. SMC header is at offset 0 if present. + readOffset := int64(0) + if hasSMCHeader { + readOffset = 512 } - // Check for and strip 512-byte SMC header - if len(data)%1024 == 512 { - data = data[512:] + // Only read what we need: up to HiROM header (0xFFC0) + header size (32 bytes) + maxNeeded := int64(snesHiROMHeaderStart + snesHeaderSize) + readSize := min(size-readOffset, maxNeeded) + + data := make([]byte, readSize) + if _, err := reader.ReadAt(data, readOffset); err != nil && err != io.EOF { + return nil, fmt.Errorf("failed to read SNES ROM: %w", err) } // Find and parse header