From 5cfd5f824223c9c371a97f9d405839643f0e35c6 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 21 Nov 2025 11:15:31 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E5=A2=9E=E5=8A=A0=E5=90=91=E9=87=8F?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E9=80=BB=E8=BE=91=E6=8F=90=E9=AB=98=E6=80=A7?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Abstractions/AbstractCacheStrategy.cs | 16 +++++++++++++--- .../Internal/ContentCacheStrategy.cs | 4 ++-- .../Internal/VectorIndexCacheStrategy.cs | 18 ++++++++---------- binding/csharp/IP2Region.Net/XDB/Searcher.cs | 7 +++++-- 4 files changed, 28 insertions(+), 17 deletions(-) diff --git a/binding/csharp/IP2Region.Net/Internal/Abstractions/AbstractCacheStrategy.cs b/binding/csharp/IP2Region.Net/Internal/Abstractions/AbstractCacheStrategy.cs index 9ba96af..e277dde 100644 --- a/binding/csharp/IP2Region.Net/Internal/Abstractions/AbstractCacheStrategy.cs +++ b/binding/csharp/IP2Region.Net/Internal/Abstractions/AbstractCacheStrategy.cs @@ -10,11 +10,21 @@ namespace IP2Region.Net.Internal.Abstractions; internal abstract class AbstractCacheStrategy(string xdbPath) { - private const int BufferSize = 4096; + private const int BufferSize = 64 * 1024; - internal int IoCount { get; private set; } + public int IoCount { get; private set; } - internal virtual ReadOnlyMemory GetData(int offset, int length) + public void ResetIoCount() + { + IoCount = 0; + } + + public virtual ReadOnlyMemory GetVectorIndexStartPos(int offset) + { + return GetData(256 + offset, 8); + } + + public virtual ReadOnlyMemory GetData(int offset, int length) { byte[] buffer = ArrayPool.Shared.Rent(length); int totalBytesRead = 0; diff --git a/binding/csharp/IP2Region.Net/Internal/ContentCacheStrategy.cs b/binding/csharp/IP2Region.Net/Internal/ContentCacheStrategy.cs index 0ef7251..94e7f51 100644 --- a/binding/csharp/IP2Region.Net/Internal/ContentCacheStrategy.cs +++ b/binding/csharp/IP2Region.Net/Internal/ContentCacheStrategy.cs @@ -10,9 +10,9 @@ namespace IP2Region.Net.Internal; class ContentCacheStrategy(string xdbPath) : AbstractCacheStrategy(xdbPath) { - ReadOnlyMemory _cacheData = ReadOnlyMemory.Empty; + ReadOnlyMemory _cacheData = default; - internal override ReadOnlyMemory GetData(int offset, int length) + public override ReadOnlyMemory GetData(int offset, int length) { if (_cacheData.IsEmpty) { diff --git a/binding/csharp/IP2Region.Net/Internal/VectorIndexCacheStrategy.cs b/binding/csharp/IP2Region.Net/Internal/VectorIndexCacheStrategy.cs index e9eb40a..4dea3fe 100644 --- a/binding/csharp/IP2Region.Net/Internal/VectorIndexCacheStrategy.cs +++ b/binding/csharp/IP2Region.Net/Internal/VectorIndexCacheStrategy.cs @@ -8,18 +8,16 @@ using IP2Region.Net.Internal.Abstractions; namespace IP2Region.Net.Internal; -internal class VectorIndexCacheStrategy : AbstractCacheStrategy +internal class VectorIndexCacheStrategy(string xdbPath) : AbstractCacheStrategy(xdbPath) { - const int HeaderInfoLength = 256; - const int VectorIndexRows = 256; - const int VectorIndexCols = 256; - const int VectorIndexSize = 8; + ReadOnlyMemory _vectorCahe = default; - readonly ReadOnlyMemory _vectorIndex; - - public VectorIndexCacheStrategy(string xdbPath) : base(xdbPath) + public override ReadOnlyMemory GetVectorIndexStartPos(int offset) { - var vectorLength = VectorIndexRows * VectorIndexCols * VectorIndexSize; - _vectorIndex = base.GetData(HeaderInfoLength, vectorLength); + if (_vectorCahe.IsEmpty) + { + _vectorCahe = base.GetData(256, 256 * 256 * 8); + } + return _vectorCahe.Slice(offset, 8); } } diff --git a/binding/csharp/IP2Region.Net/XDB/Searcher.cs b/binding/csharp/IP2Region.Net/XDB/Searcher.cs index 5fcbf30..1aa7fc6 100644 --- a/binding/csharp/IP2Region.Net/XDB/Searcher.cs +++ b/binding/csharp/IP2Region.Net/XDB/Searcher.cs @@ -40,7 +40,7 @@ public class Searcher : ISearcher public string? Search(string ipStr) { var ipAddress = IPAddress.Parse(ipStr); - return Search(ipAddress); + return SearchCore(ipAddress.GetAddressBytes()); } /// @@ -63,6 +63,9 @@ public class Searcher : ISearcher string? SearchCore(byte[] ipBytes) { + // 重置 IO 计数器 + _cacheStrategy.ResetIoCount(); + // 每个 vector 索引项的字节数 var vectorIndexSize = 8; @@ -74,7 +77,7 @@ public class Searcher : ISearcher var il1 = ipBytes[1]; var idx = il0 * vectorIndexCols * vectorIndexSize + il1 * vectorIndexSize; - var data = _cacheStrategy.GetData(256 + idx, vectorIndexSize); + var data = _cacheStrategy.GetVectorIndexStartPos(idx); var sPtr = BinaryPrimitives.ReadUInt32LittleEndian(data.Span); var ePtr = BinaryPrimitives.ReadUInt32LittleEndian(data.Span.Slice(4));