CreateOrOpen和CreateFromFile的最大区别在于,前者没有具体的文件(支持载体可以是内存,也可以是操作系统的页面文件),而后者要打开或保存一个具体的文件;前者不一定要磁盘读取和回写,而后者要读取文件和写回磁盘。由于磁盘IO比内存IO慢了太多,因此你观察到两个的速度区别。因为你的需求要读取和保存结果,这决定你只能用CreateFromFile。
你也可以试试不用MemoryMappedFile ,因为320M的内存需求不算太高,可以在内存里面直接操作数据,最后写回结果。

解决方案 »

  1.   

    1. 这个1楼说了,CreateOrOpen不是用来操作文件的,它一般都是用来做进程间通信,所以并不一定真正写到磁盘。CreateFromFile才能用来操作文件。2. 优化速度这个主要是可以优化下内存复制速度,比如http://ayende.com/blog/163138/memory-mapped-files-file-i-o-performance,使用API进行内存复制比WriteArray快了不少。不过这比FileStream的结果还慢一点点。MMF 操作文件的速度优势主要体现在减少了内存复制,如果是c/c++,可以直接和结构体映射。但是对于托管环境,很可能还是需要在托管内存中创建对象,就抵消了它的优势。所以最好像给的链接里那样,对你的场景测试下三种实现的速度,看看哪个更好。
      

  2.   


    介个,320m只是测试文件,常规可能会有几个G的,甚至十几个G,大型的模型计算,计算范围大,数据多,就是因为内存溢出才考虑使用这个。控制好视图,调整算法后,可以保证内存使用基本稳定(100m以内),目前只会这一种办法来实现。你说CreateOrOpen这个使用内存,感觉不是,之前有个测试是到3G+,是内存的话应该出问题的吧。
    下面是前后资源使用情况,粗略的看基本没多大区别,应该不是直接使用内存。
    如果是操作系统的页面文件,这个也应该有IO的吧?如果有那跟CreateFromFile也没本质区别,不该有近一倍的效率差距。
      

  3.   

    如果完全只用内存就不是‘一倍的效率差距了’:)
    如果是随机存储,内存和普通磁盘的差距可能是10万倍。即使是大块数据连续传输,差别可能到10倍。另外,直接观察物理内存可能会有误导。原因是用CreateOrOpen来做3G+,并不意味着3G+都要放到内存里,预留内存地址(preserve)并不一定要占用(commit)物理内存。其实从需求出发,你没有多少选择: 要操作具体的数据文件,那你只能用CreateFromFile。
      

  4.   

    如果完全只用内存就不是‘一倍的效率差距了’:)
    如果是随机存储,内存和普通磁盘的差距可能是10万倍。即使是大块数据连续传输,差别可能到10倍。另外,直接观察物理内存可能会有误导。原因是用CreateOrOpen来做3G+,并不意味着3G+都要放到内存里,预留内存地址(preserve)并不一定要占用(commit)物理内存。其实从需求出发,你没有多少选择: 要操作具体的数据文件,那你只能用CreateFromFile。嗯,我现在也基本只能用CreateFromFile了。现在还是纠结CreateOrOpen,想弄明白他到底怎么存取的,具体到底存哪的,效率会高些的原因。完全内存不现实,都说是映射内存文件了。
    意思CreateOrOpen是用了预留内存地址和,或者说他缓存了比CreateFromFile更多的东西?我纠结的核心看来是微软干嘛不能成一致的
    给的示例看了,也具体测试了,用内存拷贝的确快了,不过写入还是低,总体提升50%吧。不过还是有问题,用内存拷贝视图里的东西时,数据乱了。好像数据在视图内对应地址不是连续的!数据乱的还没规律可言,偏移应该是没问题的,之前直接写就对的,得到的栅格结果,可以发现部分区是正确的,只是会有不规则的位置移动,只有极少部分数据位置没变,完全找不到规律。准备放弃了。效率低点就低点吧
      

  5.   

    目前也够用,也不是说只能CreateFromFile,留了接口,让调用的自己选吧,看能否容忍加载耗时,自己平衡加载、运算耗时来选择 ,数据量不同决定,哪种调用耗时最少。还有更好的建议请留言,一天后结贴。