我使用Haskell实现了一个简单的L1距离计算器.由于我对性能感兴趣,因此我使用未装箱的矢量来存储要比较的图像.
calculateL1Distance :: LabeledImage -> LabeledImage -> Int
calculateL1Distance reference test =
let
substractPixels :: Int -> Int -> Int
substractPixels a b = abs $ a - b
diff f = Vec.sum $ Vec.zipWith substractPixels (f reference) (f test)
in
diff pixels
Run Code Online (Sandbox Code Playgroud)
据我所知(我是Haskell的新手),流融合应该使这个代码作为一个简单的循环运行.所以它应该很快.但是,编译时性能结果很低
ghc -O -fforce-recomp -rtsopts -o test .\performance.hs
Run Code Online (Sandbox Code Playgroud)
该计划耗时约60秒:
198,871,911,896 bytes allocated in the heap
1,804,017,536 bytes copied during GC
254,900,000 bytes maximum residency (14 sample(s))
9,020,888 bytes maximum slop
579 MB total memory in use (0 …
Run Code Online (Sandbox Code Playgroud) optimization performance haskell nearest-neighbor stream-fusion
以下代码意外地(至少对我而言)产生了一个中间向量:
import qualified Data.Vector as Vector
main :: IO ()
main =
print (test n)
n :: Int
n = 1000000
test :: Int -> Int
test n = Vector.length (Vector.replicate n (0 :: Int))
Run Code Online (Sandbox Code Playgroud)
Core的相关部分在这里(注意newArray# 1000000
电话):
Main.main4
:: forall s_a38t.
GHC.Prim.State# s_a38t
-> (# GHC.Prim.State# s_a38t, Vector.Vector Int #)
[GblId,
Arity=1,
Str=DmdType,
Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True,
WorkFree=True, Expandable=True, Guidance=IF_ARGS [0] 399 30}]
Main.main4 =
\ (@ s_a38t) (s1_a38u [OS=OneShot] :: GHC.Prim.State# s_a38t) ->
case GHC.Prim.newArray#
@ Int …
Run Code Online (Sandbox Code Playgroud) 这是一个简短的Haskell程序,可产生440 Hz的声音.它使用pulseaudio作为音频后端.
import GHC.Float
import Control.Arrow
import Sound.Pulse.Simple
import qualified Data.List.Stream as S
import Data.List
type Time = Double
type Frequency = Double
type Sample = Double
type CV = Double
chunksize = 441 * 2
sampleRate :: (Fractional a) => a
sampleRate = 44100
integral :: [Double] -> [Double]
integral = scanl1 (\acc x -> acc + x / sampleRate)
chunks :: Int -> [a] -> [[a]]
chunks n = S.takeWhile (not . S.null) . S.unfoldr (Just . S.splitAt …
Run Code Online (Sandbox Code Playgroud) 我有兴趣创建一个新的Haskell容器类型(严格列表),我想确保它们上的操作符合流融合的条件.如何选择ghc的流融合功能?
如果我的容器是Traversable
,它会自动融合吗?如果我实现了,说mapAccumL
来讲toList
,将哈斯克尔足够聪明,不是容器转换到一个列表所有,而不是简单地对底层表示操作?