我有一些高性能的Haskell代码 - 内部循环编译为6个汇编指令.修改内部循环效率较低并不会对性能产生任何明显影响,这表明内部循环不是瓶颈.但是,当我打开分析时,为内循环生成的汇编代码变得非常低效,并且分析器报告内循环占用85%的时间.
我怀疑某些东西是不必要的慢,但是当我使用分析来看什么时,我怀疑分析会使内循环足够慢以至于它占主导地位.我可以用什么技术来查看时间的去向?如果Haskell存在,那么采样分析器会很棒.
鉴于该计划:
import Debug.Trace
main = print $ trace "hit" 1 + trace "hit" 1
Run Code Online (Sandbox Code Playgroud)
如果我用ghc -O
(7.0.1或更高版本)编译,我得到输出:
hit
2
Run Code Online (Sandbox Code Playgroud)
即GHC使用常见的子表达式消除(CSE)来重写我的程序:
main = print $ let x = trace "hit" 1 in x + x
Run Code Online (Sandbox Code Playgroud)
如果我编译-fno-cse
然后我看到hit
出现两次.
是否可以通过修改程序来避免CSE?是否有任何子表达式e
,我可以保证e + e
不会CSE'd?我知道lazy
,但找不到任何旨在抑制CSE的东西.
这个问题的背景是cmdargs库,其中CSE打破了库(由于库中的杂质).一种解决方案是要求库的用户指定-fno-cse
,但我更喜欢修改库.
鉴于该计划:
import Language.Haskell.Exts.Annotated -- from haskell-src-exts
import System.Mem
import System.IO
import Control.Exception
main :: IO ()
main = do
evaluate $ length $ show $ fromParseResult $ parseFileContents $ "data C = C {a :: F {- " ++ replicate 400000 'd' ++ " -} }"
performGC
performGC
performGC
Run Code Online (Sandbox Code Playgroud)
使用GHC 7.0.3,当我运行时:
$ ghc --make Temp.hs -rtsopts && Temp.exe +RTS -G1 -S
Alloc Copied Live GC GC TOT TOT Page Flts
bytes bytes bytes user elap user elap
...
29463264 64 …
Run Code Online (Sandbox Code Playgroud) 我有一个包含源代码的目录,我编译它来生成目标文件.我想快速应用补丁并重建,以便我可以同时访问旧的和新的目标文件.一种方法是:
cd old && make
xcopy old new
cd new && apply diff && make
Run Code Online (Sandbox Code Playgroud)
但是,即使在同一驱动器上,副本也需要大约10分钟.如果我能new
成为一个写时复制版本old
会更快.Windows 7 NTFS可以创建写时复制目录吗?修改外部目录时,是否可以将这些目录扩展为写时复制子目录?
使用Shake Haskell构建库,如何使用需要达到固定点的程序编写规则?想象一下,我有一个程序foo
,它接受一个文件input
并生成一个输出文件,应该foo
重复应用,直到输出文件没有改变.我怎么能在Shake中写出来?
这种模式的典型例子是LaTeX.
在Shake文档中,它建议使用标志-with-rtsopts=-I0
进行编译以禁用空闲垃圾回收.为什么Shake建议这样做?
给定存在性数据类型,例如:
data Foo = forall a . (Typeable a, Binary a) => Foo a
Run Code Online (Sandbox Code Playgroud)
我想写instance Binary Foo
.我可以编写序列化(序列化TypeRep
然后序列化值),但我无法弄清楚如何编写反序列化.基本问题是,如果TypeRep
你需要映射回该类型的类型字典 - 我不知道是否可以这样做.
之前在haskell邮件列表http://www.haskell.org/pipermail/haskell/2006-September/018522.html上已经提出过这个问题,但没有给出答案.
在>>=
和>>
运营商都infixl 1
.为什么左关联?
特别是,我观察到等价:
(do a; b; c ) == (a >> (b >> c)) -- Do desugaring
(a >> b >> c) == ((a >> b) >> c) -- Fixity definition
Run Code Online (Sandbox Code Playgroud)
因此do
,对于固定性定义自然如何工作的方式不同,这是令人惊讶的.
鉴于 type std::cell::Ref
,它似乎基本上是一个指针。但它没有Hash
,PartialEq
或Eq
trait 实现。没有添加这些特征是否有任何根本原因?
我正在寻找一个库函数来将浮点数转换为字符串,然后再用C++转换回来.我想要的属性是str2num(num2str(x))== x和num2str(str2num(x))== x(尽可能).一般属性是num2str应该表示最简单的有理数,当舍入到最近的可表示的浮动指针编号时,会返回原始数字.
到目前为止,我已经尝试过boost :: lexical_cast:
double d = 1.34;
string_t s = boost::lexical_cast<string_t>(d);
printf("%s\n", s.c_str());
// outputs 1.3400000000000001
Run Code Online (Sandbox Code Playgroud)
我已经尝试过std :: ostringstream,如果我使用stream.precision(16),它似乎适用于大多数值.但是,在精度为15或17时,它会截断或给出像1.34这样的东西的丑陋输出.我不认为精度16可以保证具有我需要的任何特定属性,并且怀疑它会因许多数字而分解.
有没有一个C++库有这样的转换?或者这样的转换函数已经埋在标准库/ boost中的某个地方.
想要这些功能的原因是将浮点值保存到CSV文件,然后正确读取它们.另外,我希望CSV文件尽可能包含简单数字,以便人们可以使用它们.
我知道Haskell读/显示函数已经具有我追求的属性,BSD C库也是如此.字符串< - >双转换的标准参考是来自PLDI 1990的一对论文:
任何基于这些的C++库/函数都是合适的.
编辑:我完全清楚浮点数是十进制数的不精确表示,并且1.34 == 1.3400000000000001.但是,正如上面提到的论文指出的那样,选择显示为"1.3400000000000001"并不是理由.
编辑2:本文正是解释了我正在寻找的内容:http://drj11.wordpress.com/2007/07/03/python-poor-printing-of-floating-point/