From 97785d7fb4283ab44543926e5d237e0b3bc3b5c6 Mon Sep 17 00:00:00 2001 From: Victor Irzak Date: Wed, 14 Oct 2026 07:40:40 -0400 Subject: [PATCH] Cache the column mapping count instead of reading ConcurrentDictionary.Count Count takes every internal lock, and it ran for every cell of a query without a header row. --- src/MiniExcel.Core/Helpers/CellReferenceConverter.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/MiniExcel.Core/Helpers/CellReferenceConverter.cs b/src/MiniExcel.Core/Helpers/CellReferenceConverter.cs index 7033f754..5508fc01 100644 --- a/src/MiniExcel.Core/Helpers/CellReferenceConverter.cs +++ b/src/MiniExcel.Core/Helpers/CellReferenceConverter.cs @@ -11,6 +11,10 @@ public static class CellReferenceConverter private static readonly ConcurrentDictionary IntMappingToAlphabet = new(); private static readonly ConcurrentDictionary AlphabetMappingToInt = new(); + // ConcurrentDictionary.Count takes every internal lock, too slow for a per-cell check. + // Entries are only added, contiguously from 0, so a cached count is safe to read. + private static volatile int _mappedCount; + static CellReferenceConverter() { EnsureMappingsUpTo(GeneralColumnIndex); @@ -33,7 +37,7 @@ public static int GetNumericalIndex(string? columnName) private static void EnsureMappingsUpTo(int columnIndex) { - if (columnIndex < IntMappingToAlphabet.Count) + if (columnIndex < _mappedCount) return; if (columnIndex > MaxColumnNumber - 1) @@ -46,6 +50,8 @@ private static void EnsureMappingsUpTo(int columnIndex) IntMappingToAlphabet.TryAdd(i, name); AlphabetMappingToInt.TryAdd(name, i); } + + _mappedCount = IntMappingToAlphabet.Count; } private static string GetColumnFromIndex(int value)