2014-01-06 21 views
4

我使用http://hackage.haskell.org/package/dataenc-0.14.0.5/docs/Codec-Binary-Base64.html#v:encode,我发现,这是非常慢:Codec.Binary.Base64.encode是慢

import qualified Codec.Binary.Base64 as C 
import System.Environment 

main = do 
    [arg] <- getArgs 
    print $ length $ C.encode $ replicate (read arg) 80 

为参数10的运行时^ 5:0.5秒,2 * 10^5:3.4小号,3 * 10^5:9.4s。 但这样的事情应该在线性时间内运行?

虽然我正在寻找问题的原因 - 是否有解决方法(不同的库)?

PS:这行代码https://github.com/magthe/dataenc/blob/master/src/Codec/Binary/Base64.hs#L77看起来非常值得怀疑的(即,二次):

doEnc acc (o1:o2:o3:os) = doEnc (acC++ enc3 [o1, o2, o3]) os 
doEnc acc os = EPart acc (eI os) 

果然,采用简单的代码

encode ws = case ws of 
    [] -> [] 
    o1:ws2 -> case ws2 of 
     [] -> take 2 (enc3 [o1,0,0]) ++ "==" 
     o2:ws3 -> case ws3 of 
      [] -> take 3 (enc3 [o1,o2,0]) ++ "=" 
      o3:ws4 -> enc3 [o1,o2,o3] ++ encode ws4 

已经给出了一个大幅改善(例如,以4s编码的10^8字节)

PPS:根据以下建议,该程序

import qualified Data.ByteString as B 
import qualified Data.ByteString.Base64 as B64 
import System.Environment 

main = do 
    [arg] <- getArgs 
    print $ B.length $ B64.encode $ B.replicate (read arg) 80 

在0.4秒内编码10^8个字节。

回答

2

尝试the base64-bytestring library。处理二进制数据时通常使用ByteString将大大提高性能。列表类型作为简单的控制结构很有用,但效果不佳。