我正在尝试创建一个程序来比较运行各种haskell脚本所需的时间,稍后将用于创建图形并在GUI中显示。我曾尝试使用Haskell库创建所述GUI,但我没有太多运气,特别是因为我无法找到最新的Windows GUI库。我曾尝试使用Java来获取这些结果,但要么返回错误,要么根本没有结果。
我构建了一个最小的例子来大致展示我现在正在做的事情:
import java.io.*;
public class TestExec {
public static void main(String[] args) {
try {
Process p = Runtime.getRuntime().exec("ghc test.hs 2 2");
BufferedReader in = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
这是调用的Haskell脚本,在这种情况下是一个简单的补充:
test x y = x + y
目前根本没有存储或打印任何结果。有人有什么想法吗?
答案 0 :(得分:3)
由于您尝试将其作为可执行文件运行,因此需要提供main。在你的情况下它应该看起来像
import System.Environment
test :: Integer -> Integer -> Integer
test = (+)
main = do
[x, y] <- map read `fmap` getArgs
print $ x `test` y
这只是读取命令行参数,添加它们,然后打印它们。虽然我做了类似的事情,但是在Haskell中进行基准测试/测试要容易得多,并且以更结构化的格式将输出数据转储到文本文件中,然后用Java或任何你喜欢的语言解析/显示它。 / p>
答案 1 :(得分:2)
这主要是一个Java问题。搜索Runtime.getRuntime().exec()。
在Haskell方面,您需要编写一个独立的Haskell脚本。 @jozefg的The one没问题。您应该可以将其作为
运行runghc /path/to/script.hs 1 2
从命令行。
从Java调用它与在Java中运行任何其他外部进程没什么不同。在Clojure(一种JVM语言,我简单地使用它)我做:
user=> (def p (-> (Runtime/getRuntime) (.exec "/usr/bin/runghc /tmp/test.hs 1 2")))
#'user/p
user=> (-> p .getInputStream input-stream reader line-seq)
("3")
请注意,我使用runghc
来运行脚本(不是ghc
)。完整路径不是必需的,但可能会有所帮助。您的Java程序可以通过以下方式进行修改:
--- TestExec.question.java
+++ TestExec.java
@@ -2,7 +2,7 @@
public class TestExec {
public static void main(String[] args) {
try {
- Process p = Runtime.getRuntime().exec("ghc test.hs 2 2");
+ Process p = Runtime.getRuntime().exec("/usr/bin/runghc /tmp/test.hs 2 2");
BufferedReader in = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line = null;
修改后的版本运行Haskell脚本就好了。您可能需要更改runghc
和test.hs
位置的路径。
答案 2 :(得分:0)
首先要从输出中读取,您需要使用OutputStreamReader(p.getOutputStream())
而不是InputStreamReader
答案 3 :(得分:0)
正如我在评论中所说,这样的基准是完全错误的。基准测试应尽可能消除尽可能多的侧滑。最好的解决方案是使用criterion包。它可以根据需要生成漂亮的图形输出。
小例子:
import Criterion
import Criterion.Main
import Criterion.Config
fac 1 = 1
fac n = n * (fac $ n-1)
myConfig = defaultConfig {
cfgReport = ljust "report.html"
}
main = defaultMainWith myConfig (return ()) [
bench "fac 30" $ whnf fac 30
]
执行后,它会生成一个带有整洁交互式图表的文件“report.html”。