Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
请帮助我理解这些Clojure Hprof痕迹_Clojure_Jvm_Profiling_Hprof - Fatal编程技术网

请帮助我理解这些Clojure Hprof痕迹

请帮助我理解这些Clojure Hprof痕迹,clojure,jvm,profiling,hprof,Clojure,Jvm,Profiling,Hprof,我有一些Clojure代码,模拟然后处理数值数据。数据基本上是双值向量;处理过程主要涉及以各种方式求和它们的值。我将在下面包含一些代码,但我的问题(我认为)更一般——我只是不知道如何解释hprof结果 无论如何,我的测试代码是: (defn spin [n] (let [c 6000 signals (spin-signals c)] (doseq [_ (range n)] (time (spin-voxels c signals))))) (defn -ma

我有一些Clojure代码,模拟然后处理数值数据。数据基本上是双值向量;处理过程主要涉及以各种方式求和它们的值。我将在下面包含一些代码,但我的问题(我认为)更一般——我只是不知道如何解释hprof结果

无论如何,我的测试代码是:

(defn spin [n]
  (let [c 6000
        signals (spin-signals c)]
      (doseq [_ (range n)] (time (spin-voxels c signals)))))

(defn -main []
  (spin 4))
其中
旋转体素
应该比
旋转信号
更昂贵(尤其是重复多次时)。我可以给出较低级别的例程,但我认为这个问题更多的是关于我不理解轨迹的基本知识(见下文)

当我用lein编译这个,然后做一些简单的分析时:

> java -cp classes:lib/clojure-1.3.0-beta1.jar -agentlib:hprof=cpu=samples,depth=10,file=hprof.vec com.isti.compset.stack
"Elapsed time: 14118.772924 msecs"
"Elapsed time: 10082.015672 msecs"
"Elapsed time: 9212.522973 msecs"
"Elapsed time: 12968.23877 msecs"
Dumping CPU usage by sampling running threads ... done.
配置文件跟踪如下所示:

CPU SAMPLES BEGIN (total = 4300) Sun Aug 28 15:51:40 2011
rank   self  accum   count trace method
   1  5.33%  5.33%     229 300791 clojure.core$seq.invoke
   2  5.21% 10.53%     224 300786 clojure.core$seq.invoke
   3  5.05% 15.58%     217 300750 clojure.core$seq.invoke
   4  4.93% 20.51%     212 300787 clojure.lang.Numbers.add
   5  4.74% 25.26%     204 300799 clojure.core$seq.invoke
   6  2.60% 27.86%     112 300783 clojure.lang.RT.more
   7  2.51% 30.37%     108 300803 clojure.lang.Numbers.multiply
   8  2.42% 32.79%     104 300788 clojure.lang.RT.first
   9  2.37% 35.16%     102 300831 clojure.lang.RT.more
  10  2.37% 37.53%     102 300840 clojure.lang.Numbers.add
这很酷。到现在为止,我很高兴。我可以看出,我在数字值的一般处理上浪费时间

因此,我查看了我的代码并决定,作为第一步,我将用
d-vec
替换
vec

(defn d-vec [collection]
  (apply conj (vector-of :double) collection))
我不确定这是否足够——我怀疑我还需要在不同的地方添加一些类型注释——但这似乎是一个好的开始。因此,我再次编译并分析:

> java -cp classes:lib/clojure-1.3.0-beta1.jar -agentlib:hprof=cpu=samples,depth=10,file=hprof.d-vec com.isti.compset.stack
"Elapsed time: 15944.278043 msecs"
"Elapsed time: 15608.099677 msecs"
"Elapsed time: 16561.659408 msecs"
"Elapsed time: 15416.414548 msecs"
Dumping CPU usage by sampling running threads ... done.
EWW。因此它的速度要慢得多。个人资料呢

CPU SAMPLES BEGIN (total = 6425) Sun Aug 28 15:55:12 2011
rank   self  accum   count trace method
   1 26.16% 26.16%    1681 300615 clojure.core.Vec.count
   2 23.28% 49.45%    1496 300607 clojure.core.Vec.count
   3  7.74% 57.18%     497 300608 clojure.lang.RT.seqFrom
   4  5.59% 62.77%     359 300662 clojure.core.Vec.count
   5  3.72% 66.49%     239 300604 clojure.lang.RT.first
   6  3.25% 69.74%     209 300639 clojure.core.Vec.count
   7  1.91% 71.66%     123 300635 clojure.core.Vec.count
   8  1.03% 72.68%      66 300663 clojure.core.Vec.count
   9  1.00% 73.68%      64 300644 clojure.lang.RT.more
  10  0.79% 74.47%      51 300666 clojure.lang.RT.first
  11  0.75% 75.22%      48 300352 clojure.lang.Numbers.double_array
  12  0.75% 75.97%      48 300638 clojure.lang.RT.more
  13  0.64% 76.61%      41 300621 clojure.core.Vec.count
  14  0.62% 77.23%      40 300631 clojure.core.Vec.cons
  15  0.61% 77.84%      39 300025 java.lang.ClassLoader.defineClass1
  16  0.59% 78.43%      38 300670 clojure.core.Vec.cons
  17  0.58% 79.00%      37 300681 clojure.core.Vec.cons
  18  0.54% 79.55%      35 300633 clojure.lang.Numbers.multiply
  19  0.48% 80.03%      31 300671 clojure.lang.RT.seqFrom
  20  0.47% 80.50%      30 300609 clojure.lang.Numbers.add
我在这里包括了更多的行,因为这是我不理解的部分

究竟为什么
Vec.count
经常出现?它是一个返回向量大小的方法。属性的单行查找

我假设我的速度较慢,因为我仍然在Double和Double之间来回跳跃,当我添加更多类型注释时,情况可能会再次改善。但我不明白我现在拥有什么,所以我不太确定浮躁的福沃兹有多大意义

请问,有人能概括地解释一下上面的垃圾场吗?我保证我不会重复调用
count
——相反,我有很多映射和reduces以及一些显式循环

我想知道我是否被JIT搞糊涂了?也许我丢失了一堆信息,因为函数正在内联?哦,我使用1.3.0-beta1,因为它似乎有更合理的数字处理


[更新]我总结了我的经验,在-得到了5倍的加速(实际上是10倍,在多清理一些并移动到1.3后),尽管我从来没有理解过这一点。

只是大声说出来,看起来你的代码正在做很多与Seq的来回转换

看,这叫


因此,使用vec会使用快速向量访问,而使用d-vec会强制使用数组,并调用缓慢的java.lang.Array.getLength方法(使用反射…)

调用vec对象的seq(由vector of创建的对象)会创建一个VecSeq对象

在Veca上创建的VecSeq对象在其方法internal reduce中调用Vec.count,clojure.core/reduce使用该方法

因此,似乎由vector of创建的向量在减少时调用Vec.count。正如你提到的,代码做了大量的减少,这似乎是原因

令人毛骨悚然的是,Vec.count似乎非常简单:

clojure.lang.Counted
  (count [_] cnt)

一个不做任何计算的简单getter。

感谢您深入研究代码-这似乎是它的一部分。然而,我并没有在上面添加
d-vec
例程,而是用它来替换一个简单的
vec
。所以我仍然不明白为什么它应该改变一些事情——我的目的只是简单地对类型进行具体说明。因此,我假设
vec
与我为
d-vec
所做的不一样,但在这种情况下,什么是?
(进入(向量:双重)集合)
可能对d-vec更有效,这是惯用语,谢谢。我最终按照中的描述重写了它以使用可变数组,但这可能适用于中心循环之外。好的,我尝试使用您的建议用双向量替换一些不可变的双数组,但结果是(我可以找到)无法为它们添加类型提示,如果没有提示,我将得到动态警告(和慢代码)数据的使用位置。这似乎回答了我的问题;我不知道为什么我在将近一年前没有将其标记为正确。对不起/谢谢。
clojure.lang.Counted
  (count [_] cnt)