我要处理很大的数组,内存放不下,需要使用磁盘文件作为辅助空间。大家觉得如何能提高访问效率?

Kusk 2006-07-22 07:50:25
首先要说明的是不考虑操作系统级别提供的虚拟内存等机制,我需要我的程序对这个过程进行控制。

以下谈谈我的想法:

使用文件作为辅助空间,我觉得很直观的想法是把数据按顺序放到文件中。对于数组的一些操作,分别考虑它们的效率。

首先,遍历是没有问题的。只要扫描文件的各个数据读出即可。无论是顺序还是随机遍历,都不是太大的问题。

其次,在数据末尾追加新项也不是问题,只要在文件的末尾添加即可。

再者,修改数据也不困难,首先定位,然后重写应该就可以了(假设数据是定长的)。

现在我的问题是插入和删除操作。似乎流式文件不能直接支持这样的操作。假如要插入数据,我目前想到的方法只能是把数据一部分一部分地读出并写入新的文件,到了插入点之后再插入新数据项,再继续把剩下的数据搬移。最后把旧文件删除,用新文件代替旧文件。

同样,删除操作也只能是搬移,遇到要删除的元素则跳过,再把剩下的搬过去……

因为可能要多次进行这样的操作,而且数据量非常大,又是在磁盘上的I/O,所以效率上接受不了。不得大家有什么经验或者想法可供参考?

...全文
454 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
Kusk 2006-07-23
  • 打赏
  • 举报
回复
谢谢大家。
Jim_King_2000 2006-07-22
  • 打赏
  • 举报
回复
不一定要做插入和删除啊。可以再做一个索引文件,把主文件的顺序写进索引文件中。关键还是楼主的问题太空泛。具体一点,要实现什么数据的怎么管理。
Kusk 2006-07-22
  • 打赏
  • 举报
回复
谢谢。
goodluckyxl 2006-07-22
  • 打赏
  • 举报
回复
我提供一种方法
将数据块(数组)按照某一固定大小的文件进行存储
在内存中管理这些文件
这样可以减少你插入小数据带来提交更新时i/o开销
缺点是你需要对一定数量的文件进行有序的管理
Kusk 2006-07-22
  • 打赏
  • 举报
回复
另外lz提到向文件尾添加数据不是问题,直接添加就可以,但这个操作实际上也可能很低效,os可能无法在原地增长空间,而是重新allocate一快更大的空间,然后就现有的数据copy过去。如果很注重效率的话,比较好的做法是一开始申请一个大文件,然后所有的操作都在这个文件里面进行

--------------------------------------------------------------
你说的不对。

你不是在说vector<T>吧?只有内存数组才会这样。一般的磁盘文件系统中,磁盘上的文件都不是连续存放的,
而是以簇为单位,像链表一样一簇指向一簇,允许分开存放。否则很多情况下,例如当你下载长度
未知的文件的时候,如你所说的灾难性后果就很可能反复发生,以对于一个系统来说而效率上几乎
不可能被接受。

像Windows就采取这种非连续存放方式。缺点是会产生文件碎片。
Kusk 2006-07-22
  • 打赏
  • 举报
回复
谢谢。我大概总结一下。有通过改变数据结构实现的(链表),的确可以解决插入删除问题。效果不
错。不过要牺牲随机访问的效率(矛盾)。此外就是从内存算法中优化了。看来到目前为止还没有比
较好的解决方案。
jixingzhong 2006-07-22
  • 打赏
  • 举报
回复
恩, 楼上的似乎和楼主意思不是很一致,
楼主的意思是不考虑在 内存中操作,
而是 考虑这个 从文件中 插入和删除 有没有高效率的办法 ...

如果考虑在内存中的操作,
那么值得思考的地方就很多了,
如 数据结构的设计, 算法的设计 ...

但是对于文件的 插入和删除,
很明确, 没有高效的方法,
移动文件的内容还不如直接重新写文件 ....
jixingzhong 2006-07-22
  • 打赏
  • 举报
回复
对于 插入和删除,
如果对象是文件,
就只有这么做了 ....

楼主考虑一下,
是否有可能减少对文件的 插入和删除 操作,
(否则效率肯定不能很高,对文件操作本身就是耗时的事情,
而且还要读取后重写一个文件)

也就是说有没有办法,
如改进算法等,
在写文件之前,
预防一些可以免去的 插入和删除 ..

如果没有办法,(如 数据是不断追加的)
那么只有按照你所说的做了 ......
fflush 2006-07-22
  • 打赏
  • 举报
回复
如果要提高插入和删除的效率,你可以考虑链表来实现,也就是每一个数据记录了下一个数据在文件中的偏移量。当然,在数据量很大的时候,指针的存储本身也是很大的开销,折中的办法是将一个数据块看作链表节点,比如说16k的一个数据块,其中包含数据同时也含有指向下一个数据块的指针,并且我认为后者同时也更好的利用了磁盘io,是更好的办法

另外lz提到向文件尾添加数据不是问题,直接添加就可以,但这个操作实际上也可能很低效,os可能无法在原地增长空间,而是重新allocate一快更大的空间,然后就现有的数据copy过去。如果很注重效率的话,比较好的做法是一开始申请一个大文件,然后所有的操作都在这个文件里面进行
jixingzhong 2006-07-22
  • 打赏
  • 举报
回复
适当的 读写块 大小,
可以提高效率,
(减少读写次数是关键)
Kusk 2006-07-22
  • 打赏
  • 举报
回复
我的问题是效率,不是实现。
pigsanddogs 2006-07-22
  • 打赏
  • 举报
回复
做一个类来实现
小则放类村中实现。
大的话可做一个连表。接点值到64的很多小文件。

33,321

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧