早上好,
在我正在编写的应用程序启动时,我需要从一个文件向Dictionary<Tuple<String, String>, Int32>中读取大约1,600,000个条目。使用BinaryReader构建整个结构大约需要4-5秒(使用FileReader大约需要同样的时间)。我分析了代码,发现在此过程中执行最多工作的函数是BinaryReader.ReadString()。虽然这个进程只需要在启动时运行一次,但我想让它尽可能快。有没有什么方法可以避免BinaryReader.ReadString(),让这个过程更快?
非常感谢。
发布于 2010-10-27 17:43:32
如果您认为逐行读取文件是瓶颈,并根据其大小执行,您可以尝试一次读取所有文件:
// read the entire file at once
string entireFile = System.IO.File.ReadAllText(path);如果这没有帮助,您可以尝试添加一个带有信号量的单独线程,它将在程序启动时立即在后台开始读取,但在您尝试访问数据时阻塞请求线程。
这就是所谓的“未来”,在Jon Skeet的miscutil库中有一个实现。
在应用程序启动时,你可以这样称呼它:
// following line invokes "DoTheActualWork" method on a background thread.
// DoTheActualWork returns an instance of MyData when it's done
Future<MyData> calculation = new Future<MyData>(() => DoTheActualWork(path));然后,一段时间后,您可以访问主线程中的值:
// following line blocks the calling thread until
// the background thread completes
MyData result = calculation.Value;如果您查看Future的Value属性,您可以看到,如果线程仍在运行,它将在AsyncWaitHandle阻塞:
public TResult Value
{
get
{
if (!IsCompleted)
{
_asyncResult.AsyncWaitHandle.WaitOne();
_lock.WaitOne();
}
return _value;
}
}发布于 2010-10-27 16:45:57
您确定在继续之前一定要这样做吗?
我会检查将任务分割到一个单独线程的可能性,该线程在完成时设置一个标志。然后,您的启动代码简单地启动该线程,并继续其愉快的方式,只有在以下情况下才会暂停:
通常,速度的幻觉就足够好了,任何编写过闪屏的人都会告诉你。
如果你控制了数据,另一种可能性是以更二进制的形式存储它,这样你就可以一次命中所有数据(即,不解释数据,只读入整个数据)。当然,这使得从应用程序外部编辑数据变得更加困难,但您并没有将其作为一项要求来说明。
如果这是一个要求,或者你不能控制数据,我仍然会研究我上面的第一个建议。
发布于 2010-10-27 17:20:35
如果字符串在元组中重复,您可以重新组织您的文件,使所有不同的涉及字符串在开头,并在文件体中引用这些字符串(整数)。您的主字典不必更改,但在启动过程中需要一个临时字典,其中包含所有不同的字符串(值)及其引用(键)。
https://stackoverflow.com/questions/4031322
复制相似问题