将大量内容保存在内存中以便快速访问

时间:2018-03-11 00:19:30

标签: c#

首先,一点背景:我喜欢处理项目Euler问题(https://projecteuler.net/archives),但是其中许多需要大量繁重的计算,所以我尝试将已知的常量保存在内存中,这样它们就不必了每次重新计算。这些包括n!,nPr,nCr和素数列表。出于这个问题的目的,让我们坚持使用素数,因为任何解决方案都可以轻松移植到其他人。

问题:假设我想在内存中保存前1,000,000个素数,以便在进行大量计算时重复访问。第1,000,000个素数是15,485,863,因此这里的投注会很好。我需要以访问为O(1)的方式保存这些值,因为这些访问很多

到目前为止我尝试过的事情: 显然,我无法将所有1,000,000放在一个cs文件中,因为Visual Studio会引发一个问题。我一直试图使用部分类和2-D List<List<int>>

将其分成多个文件
public partial class Primes
{
    public readonly List<int> _primes_1 = new List<int>
    {
        2, 3, ... 999983
    }
}

所以_primes_1的素数小于1,000,000,_primes_2的素数在1,000,000到2,000,000之间,等于15个文件。然后我把它们放在一起

public partial class Primes
{
    public List<List<int>> _primes = new List<List<int>>()
    {
        _primes_1, _primes_2, _primes_3, _primes_4, _primes_5,
        _primes_6, _primes_7, _primes_8, _primes_9, _primes_10,
        _primes_11, _primes_12, _primes_13, _primes_14, _primes_15
    };
} 

这种方法确实有效,因为它很容易通过列表进行枚举,IsPrime(n)检查也很简单(二进制搜索)。这种方法的最大挫折是VS开始变得怪异,因为每个文件中有大约75,000个整数(大约8000行,取决于间距)。事实上,我对这些文件的大部分编辑都必须在NPP中完成,以防止VS挂起/崩溃。

我考虑过的其他事情: 我最初在文本文件中读取数字,并且可以在程序中执行此操作,但显然我希望在启动时执行此操作,然后只提供值。我还考虑过将它们转储到sql中,但最终还是需要在内存中。对于内存存储,我考虑了内存缓存,但我不太清楚它是否知道它在查找中的效率。

最后,这归结为两个问题:

  1. 这些数字如何进入内存开始?

  2. 用什么机制存储它们?

  3. 只要查找机制快速快速,花费更多时间进行旋转就可以了(在合理范围内)。

    快速注意:是的我知道如果我只显示15页,那么我将不会全部为1,000,000,因为15,485,863在第16页。这很好,为了我们的目的,这已经足够了。

1 个答案:

答案 0 :(得分:2)

在启动时从单个文本文件中引入它们。此数据不应位于源文件中(正如您所发现的那样)。

将它们存储在HashSet<int>中,因此适用于任何数字nisPrime = n => primeHashSet.Contains(n)。这将为您提供所需的O(1)复杂度。

HashSet<int> primeHashSet = new HashSet<int>(
    File.ReadLines(filePath)
        .AsParallel() //maybe?
        .SelectMany(line => Regex.Matches(line, @"\d+").Cast<Match>())
        .Select(m => m.Value)
        .Select(int.Parse));
Predicate<int> isPrime = primeHashSet.Contains;
bool someNumIsPrime = isPrime(5000); //for example

在我的(诚然相当活泼的)机器上,this在大约300毫秒内加载。