小编Jan*_*rek的帖子

如何可靠地比较Haskell和C的运行时?

我使用Criterion库为我的Haskell函数编写基准.现在我在C中实现相同的算法来比较Haskell的性能.问题是如何可靠地做到这一点?Criterion做了很多花哨的事情,例如计算时钟调用开销和对结果进行统计分析.我想如果我只是测量我的C函数所需的时间,它将无法与Criterion返回的结果进行比较.在他关于Criterion的原始帖子中, Bryan O'Sullivan写道:"使用标准对C代码和命令行程序进行基准测试应该很容易." 问题是如何?Takayuki Muranushi 比较了DFT的C实现使用Haskell生成线程并调用可执行文件,但我担心这会增加很多额外的开销(创建新线程,运行应用程序,输出到stdio然后从中读取),这使得结果无法比拟.我也考虑使用FFI,但我再次担心额外的开销会使这种比较不公平.

如果没有办法使用Criterion可靠地对C进行基准测试,那么您会推荐哪种C基准测试方法?我在这里读过一些关于SO的问题,似乎有许多不同的函数可以测量系统时间,但是它们要么以毫秒为单位提供时间,要么有大量的调用开销.

c benchmarking haskell haskell-criterion

14
推荐指数
1
解决办法
965
查看次数

从Haskell的Core中删除带有重复分支的"case"

我有一段看起来像这样的Haskell代码:

fst . f $ (Z :. i `div` 2)
Run Code Online (Sandbox Code Playgroud)

Z:.取自Repa库,定义如下:

data Z = Z deriving (Show, Read, Eq, Ord)
infixl 3 :. 
data tail :. head = !tail :. !head deriving (Show, Read, Eq, Ord)
Run Code Online (Sandbox Code Playgroud)

表达式右侧$定义了一个数组索引,f而是一个获取该索引并返回一对的函数.这将编译为以下Core:

case f_a2pC
       (case ># x_s32E 0 of _ {
          False ->
            case <# x_s32E 0 of _ {
              False -> :. Z (I# (quotInt# x_s32E 2));
              True -> :. Z (I# (-# (quotInt# (+# …
Run Code Online (Sandbox Code Playgroud)

haskell core repa

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

如何为Criterion基准创建数据?

我使用标准来对我的Haskell代码进行基准测试.我正在做一些繁重的计算,我需要随机数据.我写了这样的主要基准文件:

main :: IO ()
main = newStdGen >>= defaultMain . benchmarks

benchmarks :: RandomGen g => g -> [Benchmark]
benchmarks gen =
   [
     bgroup "Group"
     [
       bench "MyFun" $ nf benchFun (dataFun gen)
     ]
   ]
Run Code Online (Sandbox Code Playgroud)

我在不同的模块中为它们保留基准和数据生成器:

benchFun :: ([Double], [Double]) -> [Double]
benchFun (ls, sig) = fun ls sig

dataFun :: RandomGen g => g -> ([Double], [Double])
dataFun gen = (take 5 $ randoms gen, take 1024 $ randoms gen)
Run Code Online (Sandbox Code Playgroud)

这有效,但我有两个问题.首先,生成基准中包含的随机数据所需的时间是多少?我发现了一个涉及该主题的问题,但说实话,我无法将其应用于我的代码.为了检查是否发生这种情况,我在IO monad中编写了一个替代版本的数据生成器.我将基准列表与main(称为生成器)放在一起,用< - 提取结果,然后将其传递给基准函数.我发现性能没有差别. …

haskell haskell-criterion

10
推荐指数
1
解决办法
970
查看次数

如何检索从Haskell执行的外部程序的输出?

我想从Haskell运行外部程序并检索其输出和错误流的内容.在其中一个库中我找到了这段代码:

runProcess :: FilePath -> [String] -> IO (ExitCode, String, String)
runProcess prog args = do
  (_,o,e,p) <- runInteractiveProcess prog args Nothing Nothing
  hSetBuffering o NoBuffering
  hSetBuffering e NoBuffering
  sout  <- hGetContents o
  serr  <- hGetContents e
  ecode <- length sout `seq` waitForProcess p
  return (ecode, sout, serr)
Run Code Online (Sandbox Code Playgroud)

这是正确的做法吗?这里有一些我不理解的东西:为什么要设置流NoBuffering?为什么length sout 'seq'?这感觉就像某种黑客.此外,我想将输出和错误流合并为一个,以获得与2>&1在命令行上所做的相同的效果.如果可能,我想避免使用专用的I/O库并依赖GHC提供的标准软件包.

io haskell

8
推荐指数
1
解决办法
1709
查看次数

如果CPU支持AVX扩展,如何检查Intel内在函数?

我正在使用英特尔内在函数编写程序.我想使用_mm_permute_pd内在的,仅在具有AVX的CPU上可用.对于没有AVX的CPU我可以使用,_mm_shuffle_pd但根据规格它比它慢得多_mm_permute_pd.英特尔内部函数的头文件是否定义了允许我区分是否支持AVX的常量,以便我可以这样写:

#ifdef __IS_AVX_SUPPORTED__  // is there sth like this defined?
// use _mm_permute_pd
# else
// use _mm_shuffle_pd
#endif
Run Code Online (Sandbox Code Playgroud)

?我找到了这个教程,它展示了如何执行运行时检查,但我需要对当前机器进行静态的编译时检查.

c intel intrinsics

7
推荐指数
2
解决办法
7977
查看次数

为什么尾递归Collat​​z猜想导致堆栈溢出?

我在Scheme中写过Collat​​z猜想:

(define C
  (lambda (n)
    (cond
     ((eq? n 1) 1)
     ((even? n) (C (/ n 2)))
     (else (C (+ (* n 3) 1))))))
Run Code Online (Sandbox Code Playgroud)

这是一个尾递归调用,但是当我调用时(C 121)我得到堆栈溢出:

guile> (trace C)
(C)
guile> (C 121)
[C 121]
[C 364]
[C 182]
[C 91]
[C 274]
[C 137]
[C 412]
[C 206]
[C 103]
[C 310]
[C 155]
[C 466]
[C 233]
[C 700]
[C 350]
[C 175]
[C 526]
[C 263]
[C 790]
[C 395]
[C 1186]
ERROR: Stack overflow
ABORT: (stack-overflow)
Run Code Online (Sandbox Code Playgroud)

为什么正确的尾递归会导致溢出?如您所见,我使用Guile作为Scheme解释器(版本1.8.7).

lisp stack-overflow scheme guile collatz

6
推荐指数
1
解决办法
699
查看次数

如何在Haskell中使用rpar策略并行评估元组?

我偶然发现了Evalmonad和rpar StrategyHaskell 的问题.考虑以下代码:

module Main where

import Control.Parallel.Strategies

main :: IO ()
main = print . sum . inParallel2 $ [1..10000]

inParallel :: [Double] -> [Double]
inParallel xss = runEval . go $ xss
    where
      go []  = return []
      go (x:xs) = do
        x'  <- rpar $ x + 1
        xs' <- go xs
        return (x':xs')

inParallel2 :: [Double] -> [Double]
inParallel2 xss = runEval . go $ xss
    where
      go []  = return [] …
Run Code Online (Sandbox Code Playgroud)

parallel-processing haskell

6
推荐指数
1
解决办法
338
查看次数

Prolog中的"谁是理发师"逻辑谜题

我正在阅读Raymond Smullyan的"嘲笑模仿鸟".在书中有一个谜题是这样的:

这个故事的塞维利亚与西班牙着名的塞维利亚(实际上没有)之间的任何相似之处纯属巧合.在这个神秘的塞维利亚小镇,男性居民戴着假发,只有他们感觉喜欢的那些日子.没有两个居民在所有日子里都表现得一样; 也就是说,如果任何两个男性居民,至少有一天他们中的一个戴着假发而另一个则不戴.鉴于任何男性居民X和Y,居民Y据说是X的追随者,如果在X所有的日子里戴假发.此外,如果居民X,Y和Z,如果Z在X和Y都做的所有日子都佩戴假发,则居民Z被称为X和Y的追随者.

其中五名居民被命名为Alfredo,Bernardo,Ben-ito,Roberto和Ramano.以下事实是关于它们的:

事实1 ......贝尔纳多和贝尼托在他们的假发习惯方面相反; 也就是说,在任何一天,其中一个戴假发,另一个戴假发.

事实2:罗伯托和拉马诺同样是对立的.

事实3:拉马诺戴着假发,只有在阿尔弗雷多和贝尼托都戴上假发的那几天.

塞维利亚只有一个理发师,以下事实是关于他的:

事实4:贝尔纳多是阿尔弗雷多和理发师的追随者.

事实5:鉴于任何男性居民X,如果Bernardo是Alfredo和X的下属,那么理发师就是X的追随者.

阿尔弗雷多只穿黑色假发; 贝尔纳多只穿白色假发; 贝尼托只穿灰色假发; 罗伯托只穿红色假发; 而Ramano只戴着棕色假发.

一个复活节早晨,理发师戴着假发.他穿的是什么颜色?

我发现在Prolog中解决这个问题会很有趣,但我很早就陷入了困境:

isOpposite( bernardo, benito   ).
isOpposite( benito  , bernardo ).
isOpposite( roberto , ramano   ).
isOpposite( ramano  , roberto  ).

wears( alfredo , black ).
wears( bernardo, white ).
wears( benito  , gray  ).
wears( roberto , red   ).
wears( ramano  , brown ).

whatWearsTheBarber( WigColor ) :-
  member( Barber, [ alfredo, benito, bernardo, roberto, ramano ] ),
  wears( Barber, WigColor …
Run Code Online (Sandbox Code Playgroud)

puzzle prolog prolog-dif

4
推荐指数
1
解决办法
913
查看次数

在包含局部变量的调用上与Ltac匹配

我的目标是foo在比赛分支中包含对某些引理的调用.该调用使用R分支的本地变量作为其参数之一:

| SomeConstr => fun R => .... (foo a b c R) ....
Run Code Online (Sandbox Code Playgroud)

我想执行beta扩展,foo以便调用成为:

| SomeConstr => fun R => .... ((fun d => foo a b c d) R) ....
Run Code Online (Sandbox Code Playgroud)

这将允许我进一步概括(fun d => foo a b c d),这将不会孤独地依赖于分支本地的变量.由于我正在处理非常大的证据,我想用Ltac写这个.这是一个尝试:

match goal with
| [ |- context[(foo ?A ?B ?C ?R)] ] =>
  let d := fresh "d" in
  replace (foo A B C R) with ((fun d => foo A B …
Run Code Online (Sandbox Code Playgroud)

coq ltac

4
推荐指数
1
解决办法
101
查看次数

基于环境变量值的条件执行elisp代码

在我的.emacs配置文件中,我有以下条目:

(custom-set-variables
  (custom-set-faces
    '(font-lock-comment-face ((((class color)
                                (min-colors 8)
                                (background dark))
                                (:foreground "red"))))))
Run Code Online (Sandbox Code Playgroud)

这可以在TERM环境变量设置为时修复字体颜色screen,但在TERM设置为时将其中断xterm.有没有办法阅读的价值TERM变量和执行的代码只有当TERM的值screen?我发现这个questin略有帮助,但我仍然不知道如何在elisp中读取环境变量的值.

emacs terminal elisp

2
推荐指数
2
解决办法
961
查看次数