为什么 shake 对这个简单构建系统的进度估计非常错误?
Why is shake's progress estimation for this simple build system very wrong?
我有以下构建系统
module Main where
import Development.Shake
main :: IO ()
main = shakeArgs shakeOptions $ do
"a" %> \out -> do
need ["a.in"]
cmd_ "sleep" "10"
cmd "touch" [out]
我用 stack build
和 运行 用 stack exec myShake -- --progress a
构建。
如果我做了一个干净的构建,而不是 touch a.in
和 运行,shake 显示我非常错误的进度预测。有时它会预测 1000 分钟或更长时间。
(因为我每 5 秒在终端的标题栏中得到一个进度预测,如果我理解正确的话,我在这里只谈论第一个进度预测,因为这是我在这个版本中唯一得到的系统示例。)
我将 lts-9.6 与 stack and shake 0.16 版一起使用(通过 git + stack.yaml 中的包中的条目)。
看来第一个进度预估消息一般没什么用。对于重要的构建系统,这应该不是问题,因为它们花费的时间超过五秒。
使用这个构建系统和 --progress=1
可以看到,第一个估计是正确的,但其他的会变得更好:
module Main where
import Development.Shake
main :: IO ()
main = shakeArgs shakeOptions $ do
mapM_ (\i ->
("a." ++ show i) %> \out ->
do
need [out ++ ".in", "a." ++ show (i-1)]
cmd_ "sleep" "1"
cmd "touch" [out])
[1 .. 10]
"a.0" %> \out -> do
need ["a.0.in"]
cmd_ "sleep" "1"
cmd "touch" [out]
要尝试这个,您需要做
for i in $(seq 0 10); do touch a.$i.in; done
在您用于此示例构建系统的工作目录中。
可以在 progressDisplay
:
找到有关进度如何工作的文档
The current implementation is to predict the time remaining (based on timeTodo
) and the work already done (timeBuilt
). The percentage is then calculated as remaining / (done + remaining)
, while time left is calculated by scaling remaining by the observed work rate in this build, roughly done / time_elapsed
.
在只做一件事情的非常短的构建系统的情况下,工作率通常是垃圾 - 所以你最终用随机数(大概是大数字,获得 1000m)。
改变工作率的想法是,有时你在笔记本电脑上使用电池电源与主电源,有时你传递不同的并行标志。 Shake 很有可能应该使用一个或多个线程作为工作率的近似值,至少在开始时是这样。
我有以下构建系统
module Main where
import Development.Shake
main :: IO ()
main = shakeArgs shakeOptions $ do
"a" %> \out -> do
need ["a.in"]
cmd_ "sleep" "10"
cmd "touch" [out]
我用 stack build
和 运行 用 stack exec myShake -- --progress a
构建。
如果我做了一个干净的构建,而不是 touch a.in
和 运行,shake 显示我非常错误的进度预测。有时它会预测 1000 分钟或更长时间。
(因为我每 5 秒在终端的标题栏中得到一个进度预测,如果我理解正确的话,我在这里只谈论第一个进度预测,因为这是我在这个版本中唯一得到的系统示例。)
我将 lts-9.6 与 stack and shake 0.16 版一起使用(通过 git + stack.yaml 中的包中的条目)。
看来第一个进度预估消息一般没什么用。对于重要的构建系统,这应该不是问题,因为它们花费的时间超过五秒。
使用这个构建系统和 --progress=1
可以看到,第一个估计是正确的,但其他的会变得更好:
module Main where
import Development.Shake
main :: IO ()
main = shakeArgs shakeOptions $ do
mapM_ (\i ->
("a." ++ show i) %> \out ->
do
need [out ++ ".in", "a." ++ show (i-1)]
cmd_ "sleep" "1"
cmd "touch" [out])
[1 .. 10]
"a.0" %> \out -> do
need ["a.0.in"]
cmd_ "sleep" "1"
cmd "touch" [out]
要尝试这个,您需要做
for i in $(seq 0 10); do touch a.$i.in; done
在您用于此示例构建系统的工作目录中。
可以在 progressDisplay
:
The current implementation is to predict the time remaining (based on
timeTodo
) and the work already done (timeBuilt
). The percentage is then calculated asremaining / (done + remaining)
, while time left is calculated by scaling remaining by the observed work rate in this build, roughlydone / time_elapsed
.
在只做一件事情的非常短的构建系统的情况下,工作率通常是垃圾 - 所以你最终用随机数(大概是大数字,获得 1000m)。
改变工作率的想法是,有时你在笔记本电脑上使用电池电源与主电源,有时你传递不同的并行标志。 Shake 很有可能应该使用一个或多个线程作为工作率的近似值,至少在开始时是这样。