从内存读取和从桌面上的文件读取在性能上的区别
Difference between reading from memory and reading from a file on desk in performance
我正在开发一个 c# 项目,其中有一些文本文件(它们大约 30mb)
该程序从游戏客户端中提取这些文件。然后将内容存储在内存(列表)中以供使用。
所以我正在处理的过程是:
- 解析游戏客户端。
- 将内容保存为目录中的 txt 文件。
- 使用流reader逐行读取内容并将每一行存储在列表中。
但我的程序最终使用了大约 100MB 的 ram,这有点多,因为该程序是一个为该游戏运行多个帐户的机器人(预计 20 个帐户,所以我相信大约 2GB ram) .
如果我解析游戏客户端然后保存txt文件然后在需要时从txt文件中读取而不将内容存储在内存中会更好吗?还是性能会更差?
答案是……这取决于您的用例。
如果您经常在程序 运行 时引用存储在这些文件中的值,并且这些文件不是太大,通常将它们存储在内存中是有意义的。您获得的访问速度比从磁盘读取快得多。
此类问题的一种常用解决方案是使用缓存(例如,如果您拥有的值多于您可以在内存中存储的值)。
您可以限制缓存的大小并将最常用的变量存储在那里。让您的程序首先尝试从缓存中读取 - 如果它想要的值在那里(命中),那么工作就完成了。如果该值不存在(未命中),它将从磁盘中获取并放入缓存中以供将来参考。
如果缓存开始变得太满,可以将旧值或不太常用的值从缓存中逐出。
如果您是 运行 同一程序的多个实例,具有共同的数据,您可以使用像 Redis 这样的程序作为它们都引用的缓存。 (即 100mb 的一个实例,而不是 100mb x 机器人数量)
您可能会考虑使用内存映射文件。他们做他们听起来喜欢的事。你将一段内存映射到一个磁盘文件;您访问内存,但实际上是在触摸底层磁盘文件。好处是您可以绕过一些使用 .Net 文件操作时会遇到的正常(性能低下)文件 I/O 开销,并且您的代码看起来很干净,因为您只是在做自己想做的事情总是这样做——针对内存中的对象编写代码,而不是编写 类 来读取和写入文件。
您可能会想到内存映射文件的一种方式是,如果您熟悉操作系统如何在虚拟内存中分页。我在这里概括一下,但这不是一个糟糕的类比。
我正在开发一个 c# 项目,其中有一些文本文件(它们大约 30mb) 该程序从游戏客户端中提取这些文件。然后将内容存储在内存(列表)中以供使用。 所以我正在处理的过程是:
- 解析游戏客户端。
- 将内容保存为目录中的 txt 文件。
- 使用流reader逐行读取内容并将每一行存储在列表中。
但我的程序最终使用了大约 100MB 的 ram,这有点多,因为该程序是一个为该游戏运行多个帐户的机器人(预计 20 个帐户,所以我相信大约 2GB ram) .
如果我解析游戏客户端然后保存txt文件然后在需要时从txt文件中读取而不将内容存储在内存中会更好吗?还是性能会更差?
答案是……这取决于您的用例。
如果您经常在程序 运行 时引用存储在这些文件中的值,并且这些文件不是太大,通常将它们存储在内存中是有意义的。您获得的访问速度比从磁盘读取快得多。
此类问题的一种常用解决方案是使用缓存(例如,如果您拥有的值多于您可以在内存中存储的值)。
您可以限制缓存的大小并将最常用的变量存储在那里。让您的程序首先尝试从缓存中读取 - 如果它想要的值在那里(命中),那么工作就完成了。如果该值不存在(未命中),它将从磁盘中获取并放入缓存中以供将来参考。
如果缓存开始变得太满,可以将旧值或不太常用的值从缓存中逐出。
如果您是 运行 同一程序的多个实例,具有共同的数据,您可以使用像 Redis 这样的程序作为它们都引用的缓存。 (即 100mb 的一个实例,而不是 100mb x 机器人数量)
您可能会考虑使用内存映射文件。他们做他们听起来喜欢的事。你将一段内存映射到一个磁盘文件;您访问内存,但实际上是在触摸底层磁盘文件。好处是您可以绕过一些使用 .Net 文件操作时会遇到的正常(性能低下)文件 I/O 开销,并且您的代码看起来很干净,因为您只是在做自己想做的事情总是这样做——针对内存中的对象编写代码,而不是编写 类 来读取和写入文件。
您可能会想到内存映射文件的一种方式是,如果您熟悉操作系统如何在虚拟内存中分页。我在这里概括一下,但这不是一个糟糕的类比。