You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell中从空格分隔整数输入快速构造Vector的最优方法

最快构造Haskell Vector的实现方式

你原代码里用words生成中间列表再转Vector,确实会有额外的内存开销和数据拷贝。要做到无中间列表且最快,核心思路是用高效的输入处理(ByteString)+ 可变Unboxed Vector原地写入,直接把解析出的整数写入Vector,完全跳过列表阶段。

最优实现代码

先导入必要的高效模块:

import qualified Data.Vector.Unboxed as V
import qualified Data.Vector.Unboxed.Mutable as MV
import qualified Data.ByteString.Char8 as B
import Data.Maybe (fromJust)

然后是主逻辑:

main = do
    n <- readLn :: IO Int
    -- 读取数字行的ByteString(比String快得多)
    numLine <- B.hGetLine stdin
    -- 创建指定长度的可变Unboxed Vector
    mutableVec <- MV.new n
    -- 逐解析数字并写入可变Vector
    let writeToVec idx input
          | idx >= n = return ()
          | otherwise = case B.readInt input of
              Nothing -> error "输入格式错误"
              Just (num, rest) -> do
                  MV.write mutableVec idx num
                  -- 跳过剩余空格,继续解析下一个数字
                  writeToVec (idx + 1) (B.dropWhile B.isSpace rest)
    writeToVec 0 numLine
    -- 冻结可变Vector为不可变的最终Vector
    finalVec <- V.freeze mutableVec
    -- 这里可以对finalVec做后续操作
    return finalVec

为什么这是最快的?

  • ByteString输入处理:ByteString是连续字节数组,比Haskell默认的String(字符链表)在处理大量输入时快几个数量级,避免了链表的内存碎片化和遍历开销。
  • 无中间列表:直接把解析出的整数写入可变Vector,没有生成任何中间列表,减少了一次完整的内存分配和数据拷贝。
  • Unboxed Vector:Unboxed.Vector直接存储原始整数(而非指针),内存密度更高,访问速度更快,比普通Vector更适合数值类型。

关于你考虑的getChar+replicateM方案

这种方式效率极低,不建议用:

  • getChar是单次IO调用读一个字符,IO操作的系统开销很大,批量读取输入的效率远低于用ByteString一次性读取整行。
  • 手动逐字符解析整数需要处理空格、正负号、多位数拼接等逻辑,代码繁琐且容易出错,性能完全比不上ByteString内置的readInt高效解析。

内容的提问来源于stack exchange,提问作者Evg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 07:25:18