Concurrent Clean : String2 : 速度調査

文字列の連結に特化してテストプログラムを書いてみた

番号 内容 N=10000 N=50000
#0 文字配列 0.14 3.24
#1 文字配列 ブロック毎 0.02 0.32
#2 リスト 1.41 -
#3 リスト reverse 0.00 0.01
#4 リスト ブロック毎 0.11 2.26
#5 String2 0.00 0.04
#6 String2 ブロック毎 0.00 0.03

連結要素数が増えるにしたがって、String2の速度が圧倒的になっていくわけだけれど、単純な文字配列でも実用的な速度が出ていることも注目。

以下、テストプログラム。

module Bench2

import String2
import StdBase, OptBase, ArgEnv, OptFile
import StdDebug

Start w # (P proc print title) = cmd.[idx]
          (f,w) = trace_n title (stdio w)
          f = print (proc times) f
          (_,w) = fclose f w
        = w
  where
    args = getCommandLine
    idx = toInt (args.[1])
    times = toInt (args.[2])

    cmd :: {P}
    cmd = {P procSa  printS  "{#Char} #1"
          ,P procSb  printS  "{#Char} #2 block"
          ,P procLa  printL  "List #1"
          ,P procLb  printL  "List #2 reverse"
          ,P procLc  printL  "List #3 block"
          ,P procS2a printS2 "String2 #1"
          ,P procS2b printS2 "String2 #2 block"
          }

:: P = E.a: P (Int -> a) (a -> *File -> *File) String

printS s f = f $> s

printL [] f = f
printL [s:ss] f = f $> s |> printL ss

printS2 s f = f $> s

str =: "abc"
str2 =: S str

procSa n = f n str
  where
    f 0 s = s
    f n s = f (n - 1) (s +++ str)

procSb n = f 10 str
  where
    k = n / 10

    f 0 s = s
    f n s = f (n - 1) (s +++ g k str)

    g 0 s = s
    g n s = g (n - 1) (s +++ str)

procLa n = f n [str]
  where
    f 0 s = s
    f n s = f (n - 1) (s ++ [str])

procLb n = f n [str]
  where
    f 0 s = reverse s
    f n s = f (n - 1) [str:s]

procLc n = f 10 [str]
  where
    k = n / 10

    f 0 s = s
    f n s = f (n - 1) (s ++ g k [str])

    g 0 s = s
    g n s = g (n - 1) (s ++ [str])

procS2a n = f n str2
  where
    f 0 s = s
    f n s = f (n - 1) (s +++ str2)

procS2b n = f 10 str2
  where
    k = n / 10

    f 0 s = s
    f n s = f (n - 1) (s +++ g k str2)

    g 0 s = s
    g n s = g (n - 1) (s +++ str2)