perf: 增加向量缓存逻辑提高性能

This commit is contained in:
Argo Zhang 2025-11-21 11:15:31 +08:00
parent 87b69e6b5f
commit 5cfd5f8242
4 changed files with 28 additions and 17 deletions

View File

@ -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<byte> GetData(int offset, int length)
public void ResetIoCount()
{
IoCount = 0;
}
public virtual ReadOnlyMemory<byte> GetVectorIndexStartPos(int offset)
{
return GetData(256 + offset, 8);
}
public virtual ReadOnlyMemory<byte> GetData(int offset, int length)
{
byte[] buffer = ArrayPool<byte>.Shared.Rent(length);
int totalBytesRead = 0;

View File

@ -10,9 +10,9 @@ namespace IP2Region.Net.Internal;
class ContentCacheStrategy(string xdbPath) : AbstractCacheStrategy(xdbPath)
{
ReadOnlyMemory<byte> _cacheData = ReadOnlyMemory<byte>.Empty;
ReadOnlyMemory<byte> _cacheData = default;
internal override ReadOnlyMemory<byte> GetData(int offset, int length)
public override ReadOnlyMemory<byte> GetData(int offset, int length)
{
if (_cacheData.IsEmpty)
{

View File

@ -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<byte> _vectorCahe = default;
readonly ReadOnlyMemory<byte> _vectorIndex;
public VectorIndexCacheStrategy(string xdbPath) : base(xdbPath)
public override ReadOnlyMemory<byte> 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);
}
}

View File

@ -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());
}
/// <summary>
@ -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));