如果您感兴趣,也会问here on SO一个非常相似的问题,但正如我们将会看到该问题的接受答案并非总是如此(我的申请使用模式从来都不是这样) )。
性能确定代码由FileStream构造函数(用于打开文件)和SHA1哈希(.Net框架实现)组成。代码几乎是我在上面链接的问题中提到的C#版本。
案例1:应用程序首次启动或第N次启动,但设置的目标文件不同。现在告诉应用程序计算之前从未访问过的文件的哈希值。
案例2:应用程序现已完全终止,并再次启动,要求计算相同文件的哈希值:
问题
我的应用程序一直在使用案例1 。永远不会要求它重新计算已经访问过一次的文件的哈希值。
所以我的速率决定步骤是FileStream Constructor!有什么办法可以加速这个用例吗?
谢谢。
P.S。使用JetBrains分析器收集统计数据。
答案 0 :(得分:3)
...但目标文件集不同。
关键词,您的应用程序将无法利用文件系统缓存。就像第二次测量一样。目录信息不能从RAM中获取,因为还没有被读取,操作系统总是不得不退回到磁盘驱动器上,而且速度很慢。
只有更好的硬件才能加快速度。 50毫秒大约是主轴驱动器所需的标准时间,而20毫秒大约是这种驱动器可以使用的时间。读者头的搜寻时间是硬性的机械限制。今天,这很容易克服,SSD广泛可用并且价格合理。唯一的问题是,当您习惯了它之后,便再也不会后退了:)
答案 1 :(得分:1)
文件系统和/或磁盘控制器将缓存最近访问的文件/扇区。
速率确定步骤是读取文件,而不是构造FileStream
对象,并且当数据在缓存中时,第二次运行时速度会明显加快,这是完全正常的。
答案 2 :(得分:1)
如前所述,文件系统具有自己的缓存机制,会干扰您的测量。
但是,const tryParseBoolean = value => {
if (value === 'true') {
return true
}
if (value === 'false') {
return false
}
return value
}
const formEntriesToJson = entries => {
const data = {}
for (const [key, val] of entries) {
data[key] = tryParseBoolean(val)
}
return data
}
构造函数执行几个任务,这些任务第一次很昂贵,并且需要访问文件系统(因此某些内容可能不在数据缓存中)。出于说明性的原因,您可以看一下代码,并看到FileStream
类用于检测子要素的使用。与该类一起,Reflection被直接(用于访问当前程序集)和间接(对于CAS保护的部分,安全链接要求)大量使用。反射引擎拥有自己的缓存,并且在其缓存为空时需要访问文件系统。
两个测量值是如此不同,感觉有点奇怪。当前,我们的计算机上配备了配置了实时防护的防病毒软件,具有类似的功能。在这种情况下,防病毒软件位于中间,并且缓存的首次访问或丢失取决于该软件的实现。
由于已知的解码漏洞,防病毒软件可能会决定主动检查某些图像文件,例如PNG。这样的检查会导致额外的速度降低,并占用最外层.NET类(即CompatibilitySwitches
类)中的时间。
使用本机符号和/或内核调试进行分析,应该可以为您提供更多见识。
根据我的经验,您无法描述您所描述的内容,因为我们无法控制多个隐藏层。根据您的用法(目前尚不十分清楚),您可以将应用程序置于服务中,因此可以更快地处理所有后续请求。或者,您可以将多个请求批量处理到一个调用中,以实现摊销的成本降低。
答案 3 :(得分:1)
偏离轨道的建议,但这是我做了很多事情,使我们的分析速度提高了30%-70%:
缓存
编写另一段代码,将:
现在,在应用程序启动时,不要调用FileStream
构造函数来计算哈希。相反,请打开(可能大得多)较小的索引文件,并从中读取预先计算的哈希值。
此外,如果这些文件是在每次启动应用程序之前重新创建的日志等文件,请在文件创建器中添加代码,以使用新创建的文件的哈希值更新索引文件。
这样,您的应用程序始终只能从索引文件中读取哈希。
我同意@HansPassant关于使用SSD来提高磁盘读取速度的建议。这个答案和他的答案是免费的。您可以同时实现这两者以最大化性能。
答案 4 :(得分:-1)
您应该尝试使用原生FILE_FLAG_SEQUENTIAL_SCAN
,您必须按CreateFile
进行操作才能获得处理并将其传递给FileStream