【发布时间】:2016-10-07 09:24:24
【问题描述】:
我想用 Java 循环在 Java 中实现一个天真的非懒惰 map。
我主要关心的是 Clojure 在 java 中的函数调用。
这是我的代码:
一个名为 NaiveClojure 的类,用于使用 Java 实现功能
package java_utils;
import java_utils.ApplyFn;
public class NaiveClojure {
public static Object[] map (ApplyFn applyfn, Object function, Object[] coll) {
int len = coll.length;
for (int i = 0 ; i < len ; i++) {
coll[i] = applyfn.apply(function, coll[i]);
}
return coll;
}
}
一个叫做 ApplyFn 的抽象类
package java_utils;
public abstract class ApplyFn {
public abstract Object apply (Object function, Object value);
}
所以在 Clojure 中我有
(defn java-map [f coll]
(let [java-fn (proxy [ApplyFn] []
(apply [f x]
(f x)))]
(seq (NaiveClojure/map java-fn f (to-array coll)))))
我试过了
(doall (map inc (range 0 10000))) ;; 3.4 seconds for 10000 operations
(java-map inc (range 0 10000) ;; 5.4 seconds
我的意思不是要超越 map(我作为示例实现了它),我只是想用特定的功能做类似的事情(而不是重新发明 Clojure 的轮子)。
有没有更好的方法来传递这样的函数? (作为一种简单快捷的方式) 为了提高我的一般编码(我的理论知识很差),你知道什么是杀死性能吗? 我会说像 Object 这样的一般类型,但我没有看到其他任何东西
谢谢
【问题讨论】:
-
这不是进行性能测量的可靠方法(检查标准),并且低于 x2 的减速几乎不会“杀死性能”。您包装 Clojure 函数的唯一事实可以解释为什么它更慢(因为您正在做更多的工作)。
-
哦,谢谢你的库名称,事实上,我的函数似乎比具有时间和标准台的序列上的 clojure map 更快。我只是想知道使用 IFn 或更好的方法是否会产生更好的结果
-
如果它更快,可能是因为您正在就地更新数组(这与 clojure.core/map 的语义不相同!)
-
是的,当然,我的意思是用它来实现不需要Clojure map的灵活性和能力的“精确”本地工作
标签: clojure clojure-java-interop