小编Dan*_*íaz的帖子

截断到Word类型

下面的代码在类型Double中将一些类型截断为一个Word16(虽然我怀疑任何其他单词类型的行为类似,但我必须为示例选择一个).

truncate1 :: Double -> Word16
truncate1 = fromIntegral . (truncate :: Double -> Int)
Run Code Online (Sandbox Code Playgroud)

正如你可以阅读的那样,我首先将其截断为Int,然后才将其转换为Word16.我直接截断这个函数的基准测试:

truncate2 :: Double -> Word16
truncate2 = truncate
Run Code Online (Sandbox Code Playgroud)

令我惊讶的是,第一个版本(通过Int类型优先)表现得更好.或者第二个更糟糕.根据标准输出:

benchmarking truncate/truncate1
mean: 25.42399 ns, lb -47.40484 ps, ub 67.87578 ns, ci 0.950
std dev: 145.5661 ns, lb 84.90195 ns, ub 244.2057 ns, ci 0.950
found 197 outliers among 100 samples (197.0%)
  97 (97.0%) low severe
  100 (100.0%) high severe
variance introduced by outliers: 99.000% …
Run Code Online (Sandbox Code Playgroud)

haskell

12
推荐指数
1
解决办法
863
查看次数

在索引处打破列表

我今天有一个表现问题.

我正在编写一个(Haskell)程序,在进行性能分析时,我发现大部分时间花在了下面的函数中.它的目的是获取列表的第n个元素,并返回除了元素本身之外没有它的列表.我目前的(慢)定义如下:

breakOn :: Int -> [a] -> (a,[a])
breakOn 1 (x:xs) = (x,xs)
breakOn n (x:xs) = (y,x:ys)
 where
  (y,ys) = breakOn (n-1) xs
Run Code Online (Sandbox Code Playgroud)

Int参数是已知的范围内1..n,其中n是(不能为null)列表的长度(x:xs),因此函数从未产生误差.

但是,我在这里表现不佳.我的第一个猜测是我应该更改另一个结构的列表.但是,在开始选择不同的结构和测试代码(这将花费我很多时间)之前,我想在这里询问第三人的意见.另外,我很确定我没有以最好的方式做到这一点.欢迎任何指示!

请注意,该类型a可能不是一个实例Eq.

SequenceData.Sequence模块调整了我的代码tu use .结果如下:

import qualified Data.Sequence as S

breakOn :: Int -> Seq a -> (a,Seq a)
breakOn n xs = (S.index zs 0, ys <> (S.drop 1 zs))
 where
  (ys,zs) = S.splitAt (n-1) xs …
Run Code Online (Sandbox Code Playgroud)

performance haskell

9
推荐指数
1
解决办法
144
查看次数

Pointfree版本使性能恶化

好吧,事实证明我在程序代码中定义了这个函数:

st_zipOp :: (a -> a -> a) -> Stream a -> Stream a -> Stream a
st_zipOp f xs ys = St.foldr (\x r -> st_map (f x) r) xs ys
Run Code Online (Sandbox Code Playgroud)

它做了它似乎做的事情.它Stream a使用类型的内部运算符拉链(应用运算符几次,是)两个类型的元素,这是类似列表的类型a.定义非常简单.

一旦我以这种方式定义了函数,我就尝试了另一个版本:

st_zipOp :: (a -> a -> a) -> Stream a -> Stream a -> Stream a
st_zipOp = St.foldr . (st_map .)
Run Code Online (Sandbox Code Playgroud)

据我所知,这与上面的定义完全相同.它只是前一个定义的无点版本.

但是,我想检查是否有任何性能变化,我发现,实际上,无点版本使程序运行稍差(内存和时间).

为什么会这样?如果有必要,我可以编写一个再现此行为的测试程序.

我正在编译,-O2如果这有所作为.

简单的测试案例

我写了下面的代码,试图重现上面解释的行为.我这次使用了列表,并且性能的变化不太明显,但仍然存在.这是代码:

opEvery :: (a -> a -> a) -> [a] …
Run Code Online (Sandbox Code Playgroud)

performance haskell pointfree

7
推荐指数
1
解决办法
383
查看次数

无符号整数函数的性能改进

任何Word32数字都可以表示为Word8数字的线性组合,如下所示:

x = a + b * 2^8 + c * 2^16 + d * 2^24
Run Code Online (Sandbox Code Playgroud)

换句话说,这是x在基础中的表示2^8.为了获得这些因素,我实现了以下功能:

word32to8 :: Word32 -> (Word8,Word8,Word8,Word8)
word32to8 n = (fromIntegral a,fromIntegral b,fromIntegral c,fromIntegral d)
  where
   (d,r1) = divMod n  (2^24)
   (c,r2) = divMod r1 (2^16)
   (b,a)  = divMod r2 (2^8)
Run Code Online (Sandbox Code Playgroud)

它工作正常,但是,由于我的程序多次使用这个函数,我认为你们可以让我知道如何改进(如果可能的话)这个操作的性能.无论是时间还是空间,任何微小的改进对我都有好处.对我来说,它看起来很简单,无法实现性能提升,但我仍然想问这个问题,以防万一我遗漏了什么.

顺便说一句,我对所有的重复感到恼火fromIntegral,但转换是必要的,所以类型可以匹配.

提前致谢.

performance haskell

3
推荐指数
1
解决办法
225
查看次数

标签 统计

haskell ×4

performance ×3

pointfree ×1