私は、csvファイルの列を並べ替える最速の方法を見つけようとしています(セルにカンマがない単純なcsvサブセットを使用しています)。私がVector.backpermuteで行っている並べ替えとそれは問題ありません。 RTS -pで示されるボトルネックは、この操作を行うベクトルのベクトルの構築です。以下のコードは私が思いつくことができる最速のバージョンです。誰にでもアイデアはありますか?あなたは、引数の解析ビットを無視することができますので、私はそのcsvファイルのすべての行の第二、その後、最初の列を与えると言う$ reorder 2,1 x.csv
: csvファイルをベクトルのベクトルに解析してから吐き出す最速の方法は?
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Applicative
import Control.Monad
import qualified Data.ByteString as B
import qualified Data.ByteString.Builder as BB
import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString.Lazy.Char8 as BL8
import Data.Char
import Data.Foldable
import Data.Monoid
import qualified Data.Vector as V
import Data.Word
import Debug.Trace
import System.Environment
import System.IO
data Args = Args { cols :: V.Vector Int, filePath :: FilePath } deriving (Show)
--
w8 = fromIntegral . ord
mconcat' :: (Foldable t, Monoid a) => t a -> a
mconcat' = foldl' (<>) mempty
parseArgs :: [String] -> Args
parseArgs [colStr, filePath] = Args ((\n -> n-1) . read <$> V.fromList (split ',' colStr)) filePath
where split :: Char -> String -> [String]
split d str = gosplit d str []
gosplit d "" acc = reverse acc
gosplit d str acc = gosplit d (drop 1 $ dropWhile (/= d) str) $ takeWhile (/= d) str : acc
reorder :: Args -> BL.ByteString -> BB.Builder
reorder (Args cols _) bstr =
-- transform to vec matrix
let rows = V.filter (not . BL.null) $ V.fromList $ BL.split (w8 '\n') bstr
m = (V.fromList . BL.split (w8 ',')) <$> rows -- n^2
-- reorder
m' = (flip V.backpermute) cols <$> m
-- build back to bytestring
numRows = length m'
numCols = length cols
builderM = mconcat' . V.imap (\i v -> BB.lazyByteString v <> (if i < numCols - 1 then "," else "")) <$> m'
builderM' = mconcat' . V.imap (\i v -> v <> (if i < numRows - 1 then "\n" else "")) $ builderM
in builderM'
main :: IO()
main = do
args <- parseArgs <$> getArgs
withFile (filePath args) ReadMode $ \h -> do
csvData <- BL.hGetContents h
BB.hPutBuilder stdout $ reorder args csvData
プログラム
は次のように呼び出されます。
お返事ありがとうございます!私は最初の数回の繰り返しで実際にキャッサバを試しましたが、ちょうどそうでしたので、ずっと遅くなりました... – asg0451
Aww、それは残念です。私は 'pipes-csv'についても考えていました。おそらく、いくつかのストリーミングプロパティを悪用しようとしているので、より小さなデータセットでメイン操作を行うことができます。これは、ベクトルの1つの巨大ベクトルを作成してから、それをByteStringに書き戻す前にすべて並べ替えるように見えます。一度に1つの行だけを考え、最後にビルダーに結果をストリーミングするだけで、マトリックスを再構築するのではなく、より良いパフォーマンスを得ることができます。 –
ええ。私もそのアプローチを試みた。まだ非常に遅いです。ベンチマークは計算時間がすべてキャッサバにあることを示していたため、私はそれをカットして未加工ベクトルに頼っていましたが、それでもまだ建設コストがかかりますが、それよりも小さいものでした。 私はそれを使用していたときにキャッサバが私の最大のボトルネックだったので、私はパイプ-CSVを試しました。 – asg0451