2010-01-19 56 views
6

在我们的软件中,我们创建记录并将它们存储在二进制文件中。一旦写操作完成,我们读回这个二进制文件。问题是如果这个二进制文件小于100 MB,那么它的性能足够好,但是一旦这个文件变大,它的性能就会受到影响。降低性能编写大型二进制文件

所以,我想将这个大的二进制文件(> 100 MB)拆分成更小的(< 100 MB)。但似乎这个解决方案没有获得性能。所以,我只是在想什么可以更好地处理这种情况?

这对你们来说非常有帮助。

感谢

+0

也许性能下降不是由于文件,而是由于内存。当你写回读文件时,你的意思是读整个文件吗?即使100 MB与当前系统相比并不是很多,但如果内存中的负载意味着增加了结构,链接以及从文件读取内容的计算值,则可能会增加内存使用量。 – 2010-01-19 10:45:54

+0

这里所提出的解决方案可能会做出快速修复,但是您应该真正重新考虑整个程序架构。 – Thorsten79 2010-01-19 10:54:31

回答

4

也许你可以尝试使用Sqlite数据库,而不是。

+1

sqlite有助于提高数据完整性,但以我的经验来看,它实际上会降低IO交易的IO吞吐量。 – 2010-01-19 08:07:07

0

如果您的应用正在读取数据顺序迁移到数据库无助于提高性能。如果使用随机访问,则应考虑将数据移入数据库,尤其是在使用不同索引的情况下。您应该检查是否有足够的资源可用,如果完全加载到内存虚拟内存管理可能会影响性能(交换,分页)。根据您的操作系统设置,可以达到文件io缓冲区的限制。文件系统本身可能被分割。 为了获得更高质量的答案,您应该提供有关硬件,操作系统,内存和文件系统的信息。而你的数据文件的使用方式。比你可以得到关于内核调优等的提示。

+0

感谢您的评论。 雅我的应用程序正在顺序读取数据。正如你所说,如果文件被加载到内存虚拟内存管理,那么它的性能可能会增加,所以你的意思是说我应该使用内存映射功能。这个应用程序运行在Windows上。 – Manish 2010-01-19 09:25:01

+0

你可以尝试关闭虚拟内存,只是谷歌:Windows防止交换。 – stacker 2010-01-19 10:17:02

+0

检查窗口工具perfmon – stacker 2010-01-19 11:48:32

0

那么这里的检索机制是什么?您的应用程序如何知道要查找哪个较小的文件以查找记录?如果你没有实现某种形式的键控查询(索引,分区)而将大文件分割开来 - 你没有解决这个问题,只是重新安排了它。

当然,如果您已经实现了某种形式的索引,那么您已经开始构建自己的数据库。

不知道更多关于您的应用程序,这将是我们提出具体建议的皮疹。也许解决方案是应用RDBMS解决方案。可能NoSQL方法会更好。也许你需要一个文本索引和检索引擎。

因此...

您的应用程序需要多长时间检索记录?它如何决定要获取哪些记录?你对表现不佳的定义是什么?为什么你(你的项目)决定首先使用平面文件而不是数据库?我们在谈论什么类型的记录?

+0

因为我从二进制文件顺序读数据,所以我没有想到实现逻辑键控查找。一旦读取整个二进制文件,我们不会再读它,因为这整个数据输入一些其他效用。 – Manish 2010-01-19 09:18:07

1

只有系统一瞥才能提供准确的答案总是相当困难,但是您是否真的尝试过检查实际吞吐量?作为第一个解决方案,我只是推荐使用专用磁盘(因此没有来自其他进程的并发读取/写入操作),并且是一个快速的磁盘。这种方式只是硬件升级的一些成本,我们都知道硬件通常比软件更便宜;)您甚至可以使用RAID控制器来实现吞吐量最大化。

如果你仍然受到磁盘吞吐量的限制,那么使用闪存技术的新技术有:USB密钥(虽然看起来不是很专业),或者“新”固态硬盘可能提供的吞吐量比机械盘。

现在,如果磁盘的方法是不够快,或者你不能让你的手好固态硬盘,你还有其他的解决方案,但它们涉及软件的变化,我建议他们把我的帽子的顶部。

  • 套接字方式:第二个实用程序正在侦听端口并将数据发送到那里。在本地计算机上它速度相对较快,并且也可以并行处理工作,所以即使数据量增大,您仍然可以开始相当快地处理。
  • 内存映射方式:写信给在现场存储器中的专用区域,并具有从该区域读取工具(Boost.Interprocess可能会有帮助,也有其他的解决方案)。

请注意,如果读取是顺序的,我觉得尝试'pipe'方法(ala Unix)更“自然”,以便两个进程同时执行。在传统的管道中,数据可能无法击中磁盘。

一种耻辱,是不是,在这个年龄段的压倒性处理能力,我们仍然与我们的磁盘IO挣扎?