caching - 在C#内存中实现文本索引

标签 caching memory

我有一个对性能敏感的任务,我正在考虑在内存中存储大约 100,000 个项目的所有对象。 (在ms sql中持久化,但在内存中复制以提高复杂搜索性能)

按键搜索速度足够快,但按文本搜索,例如。 Contains 相对较慢 - 每个查询大约需要 30 毫秒,如下所示:

IEnumerable<Product> result =
   products.Where(p =>
   p.Title.Contains(itemnames[rnd.Next(itemnames.Length)]));

我已经尝试过使用内存数据库 db4o,但它的性能更差 - 在 100K 项中每次搜索大约需要 1.5 秒。

有哪些选项可以避免检查每个对象标题并更快地执行此操作?

我可以使用什么内存数据库来解决这个任务?

最佳答案

您可以选择更改存储产品的数据结构吗?加快“包含”搜索速度的一种方法是存储所有可能的 Product.Title Dictionary<string, List<Product>> 中的子字符串。这将使您的搜索时间复杂度为 O(1) 而不是 O(n)。

您可以像这样生成每个子字符串:

public static IEnumberable<string> AllSubstrings(this string value)
{
    int index = 0;
    while(++index <= value.Length)
    {
        yield return value.Substring(0, index);
    }

    index = 0;
    while(++index <= value.Length - 1)
    {
        yield return value.Substring(index);
    }
}

然后你可以像这样填充你的字典:

var titleIndex = new Dictionary<string, List<Product>>();

foreach(Product product in products)
{
    foreach(string substring in product.Title.AllSubstrings())
    {
        if(titleIndex.ContainsKey(substring))
        {
            index[substring].Add(product);
        }
        else
        {
            index[substring] = new List<Product> { product };
        }
    }
}

最后,您可以像这样执行搜索:

string searchString = itemnames[rnd.Next(itemnames.Length)];

if(titleIndex.ContainsKey(searchString))
{
    List<Product> searchResults = titleIndex[searchString];
}

注意:正如您可能已经猜到的,这样存储数据需要预先花费更多的 CPU 时间并使用更多的 RAM。

关于caching - 在C#内存中实现文本索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5130636/

相关文章:

c - 访问C中的外部分配空间

Java:本身的类和内存使用情况(例如:简单的二叉树实现)?

java - 为什么无法在托管环境中测量对象大小?

php - CakePHP Cache::write() 键可以按模型分组吗?

memory - 如何获得CR3值?

arrays - MIPS 钻石分选

performance - Spark 。数据缓存?

caching - Cloudfront私有(private)内容+签名url架构

ios - 使用 AFNetworking API 的 NSURLCache 图像

python - 如何在测试中清除/无效 NDB 缓存