我进行了一项小测试,我强烈建议使用内存映射文件。我创建了一个包含350M个双精度值的文件(正如之前许多人提到的那样,大小为2.6GB),然后测试了将文件映射到内存所需的时间,以及访问任何元素所需的时间。
在我的笔记本电脑上进行的所有测试(Win7、.Net 4.0、Core2 Duo 2.0 GHz、4GB RAM)中,映射文件所需的时间都不到一秒钟,在那一点上访问任何元素几乎需要0毫秒(所有时间都用于验证索引)。
然后,我决定遍历所有350M个数字,整个过程大约需要3分钟(包括分页),因此如果您必须迭代,可能还有另一种选择。
尽管如此,出于示例目的,我对访问进行了包装,您在使用此代码之前应检查许多条件。代码如下:
以下是一个关于IT技术的类的代码,这个类可以用来操作内存映射文件。这个类实现了IDisposable接口和IEnumerable<T>接口,其中T是一个结构体类型。这个类有一个构造函数,需要传入一个文件路径作为参数。如果文件路径为空或者文件不存在,会抛出相应的异常。这个类还有一个Length属性,可以获取元素数量。这个类还有一个索引器,可以通过索引获取元素的值。这个类还实现了GetEnumerator()方法,可以返回一个IEnumerator<T>类型的迭代器,可以用foreach语句进行遍历。这个类还有一个静态方法GetArray(string filePath),可以返回一个T类型的数组,可以用来读取内存映射文件中的所有元素。在使用这个类的时候,可以参考下面的示例代码。
Stopwatch watch = Stopwatch.StartNew();
using (Storage<double> helper = new Storage<double>("Storage.bin"))
{
Console.WriteLine("初始化时间: {0}", watch.ElapsedMilliseconds);
string item;
long index;
Console.Write("要显示的项: ");
while (!string.IsNullOrWhiteSpace((item = Console.ReadLine())))
{
if (long.TryParse(item, out index) && index >= 0 && index < helper.Length)
{
watch.Reset();
watch.Start();
double value = helper[index];
Console.WriteLine("访问时间: {0}", watch.ElapsedMilliseconds);
Console.WriteLine("项: {0}", value);
}
else
{
Console.Write("无效的索引");
}
Console.Write("要显示的项: ");
}
}
更新:我添加了一个静态方法,将文件中的所有数据加载到数组中。显然,这种方法最初需要更多的时间(在我的笔记本电脑上需要1到2分钟),但之后的访问性能符合你对 .Net 的期望。如果您需要频繁访问数据,则此方法应该很有用。
使用方法非常简单:
double[] helper = Storage<double>.GetArray("Storage.bin");
希望这可以帮到你。