File 如何将文件读入双精度向量?
我有一个文件名(作为字符串),该文件包含一定数量(例如1000000个)的双精度浮点值(存储为二进制,显然每个8字节)File 如何将文件读入双精度向量?,file,haskell,File,Haskell,我有一个文件名(作为字符串),该文件包含一定数量(例如1000000个)的双精度浮点值(存储为二进制,显然每个8字节) 将这些双精度读入向量的最佳方法是什么?以下是我最后的做法: import qualified Data.Vector.Unboxed as V import qualified Data.Vector.Unboxed.Mutable as VM import qualified Data.ByteString.Lazy as BS import Data.Binary impo
将这些双精度读入向量的最佳方法是什么?以下是我最后的做法:
import qualified Data.Vector.Unboxed as V
import qualified Data.Vector.Unboxed.Mutable as VM
import qualified Data.ByteString.Lazy as BS
import Data.Binary
import Data.Binary.Get
import System.IO.Unsafe (unsafePerformIO)
import Unsafe.Coerce
readDoubles :: Int -> FilePath -> IO (V.Vector Double)
readDoubles n f = BS.readFile f >>= return . runGet (getVector n)
getVector :: Int -> Get (V.Vector Double)
{-# INLINE getVector #-}
getVector n = do
mv <- liftGet $ VM.new n
let fill i
| i < n = do
x <- fmap unsafeCoerce getWord64be
(unsafePerformIO $ VM.unsafeWrite mv i x) `seq` return ()
fill (i+1)
| otherwise = return ()
fill 0
liftGet $ V.unsafeFreeze mv
liftGet :: IO b -> Get b
liftGet = return . unsafePerformIO
import qualified Data.Vector.unbox为V
将限定的Data.Vector.unbox.Mutable导入为VM
将限定数据.ByteString.Lazy导入为BS
导入数据。二进制
导入Data.Binary.Get
导入System.IO.Unsafe(unsafePerformIO)
导入不安全。强制
readDoubles::Int->FilePath->IO(V.Vector Double)
readDoubles n f=BS.readFile f>>=return。runGet(getVector n)
getVector::Int->Get(V.Vector双精度)
{-#内联getVector}
getVector n=do
mv你在使用Hackage的二进制软件包吗?@jozefg-是的,目前我正试图使用该软件包组装一些东西。@Rogach看看@MikhailGlushenkov-我已经做了。我们在#haskell irc进行了一次非常有趣的讨论,最终找到了解决方案。除非有人给出更好的答案,否则我会发布解决方案。这里真的需要所有不安全的东西吗?我希望一个简单的V.replicateM n get
来完成这项工作。@hammar-如果我将getVector
定义为V.replicateM n get
,我会得到一个错误字节太少。尝试读取文件时,在字节位置8000001处读取失败。这是由于Get
实例中的一些bug导致的Double
。为了避免这种情况,我使用了不安全的强制(同样,简单的强制比任何其他方法快2倍)——但是,如果我将getVector
定义为V.replicateM n(fmap unsafeceorce getWord64be)
,我仍然会得到堆栈溢出。