Performance 为什么不是';t当主要组成函数显示性能加速时,该函数是否显示性能加速?

Performance 为什么不是';t当主要组成函数显示性能加速时,该函数是否显示性能加速?,performance,clojure,jvm,Performance,Clojure,Jvm,我正在优化一个我一直在做的程序,结果遇到了麻烦。函数julia subrect为每个像素映射了大量的。我优化了每个像素的,使其加速约16倍。然而,我的优化版的julia subrect没有显示这一点。以下是我的基准测试和相关代码: ; ======== Old `for-each-pixel` ======== ;(bench (julia/for-each-pixel (->Complex rc ic) max-itrs radius r-min x-step y-step [xt yt

我正在优化一个我一直在做的程序,结果遇到了麻烦。函数
julia subrect
为每个像素映射了大量的
。我优化了每个像素的
,使其加速约16倍。然而,我的优化版的julia subrect没有显示这一点。以下是我的基准测试和相关代码:

; ======== Old `for-each-pixel` ========
;(bench (julia/for-each-pixel (->Complex rc ic) max-itrs radius r-min x-step y-step [xt yt])))
;Evaluation count : 3825300 in 60 samples of 63755 calls.
;Execution time mean : 16.018466 µs

; ======== New `for-each-pixel`.  optimized 16x. ========
;(bench (julia/for-each-pixel-opt [rc ic] [max-itrs radius r-min] [x-step y-step] [xt yt])))
;Evaluation count : 59542860 in 60 samples of 992381 calls.
;Execution time mean : 1.038955 µs

(defn julia-subrect [^Long start-x ^Long start-y ^Long end-x ^Long end-y ^Long total-width ^Long total-height ^Complex constant ^Long max-itrs]
  (let [grid (for [y (range start-y end-y)]
               (vec (for [x (range start-x end-x)]
                      [x y])))
        radius (calculate-r constant)
        r-min (- radius)
        r-max radius
        x-step (/ (Math/abs (- r-max r-min)) total-width)
        y-step (/ (Math/abs (- r-max r-min)) total-height)
        ; Uses old implementation of `for-each-pixel`
        calculate-pixel (partial for-each-pixel constant max-itrs radius r-min x-step y-step)
        for-each-row (fn [r] (map calculate-pixel r))]
    (map for-each-row grid)))
; ======== Old `julia-subrect` ========
;(bench (doall (julia/julia-subrect start-x start-y end-x end-y total-width total-height c max-itrs))))
;Evaluation count : 22080 in 60 samples of 368 calls.
;Execution time mean : 2.746852 ms

(defn julia-subrect-opt [[^long start-x ^long start-y ^long end-x ^long end-y] [^double rc ^double ic] total-width total-height max-itrs ]
  (let [grid (for [y (range start-y end-y)]
               (vec (for [x (range start-x end-x)]
                      [x y])))
        radius (calculate-r-opt rc ic)
        r-min (- radius)
        r-max radius
        x-step (/ (Math/abs (- r-max r-min)) total-width)
        y-step (/ (Math/abs (- r-max r-min)) total-height)
        ;Uses new implementation of `for-each-pixel`
        calculate-pixel (fn [px] (for-each-pixel-opt [rc ic] [max-itrs radius r-min] [x-step y-step] px))
        for-each-row (fn [r] (map calculate-pixel r))]
    (map for-each-row grid)))
; ======== New `julia-subrect`, but no speedup ========
;(bench (doall (julia/julia-subrect-opt [start-x start-y end-x end-y] [rc ic] total-width total-height max-itrs))))
;Evaluation count : 21720 in 60 samples of 362 calls.
;Execution time mean : 2.831553 ms
以下是我指定的所有函数的源代码要点:


那么,谁能告诉我为什么julia subrect没有显示加速的迹象?另外,我对clojure还是个新手,所以如果代码不符合标准/难看,请容忍我。现在,我专注于让程序运行得更快

作为一般指南:

  • 个人资料
  • 真正开始分析,就像真实的;-)
  • 删除反射(看起来像是您这样做的)
  • 将操作拆分为易于思考的函数
  • 消除惰性(传感器应为本部分的最后一步)
  • 使用loop/recur组合步骤,使您的代码无法理解,并且速度稍快(出于某种原因,这是最后一步)
  • 具体考虑您发布的代码:

    乍一看,这个函数将花费大量时间在for循环中生成一个值的惰性列表,然后立即实现(评估为不再是惰性的),因此生成该结构所花费的时间被浪费了。你可以考虑改变它来直接产生向量,<代码> MAPV是有用的。 第二部分是为每一行调用
    map
    in,这将产生大量中间数据结构。您可以考虑使用一个非懒惰的表达式,如<代码> MAVV<代码>或<代码>循环<代码> />代码> ReCurr> <代码> .<
    看起来您已经完成了步骤2-4,并且没有明显的理由跳到步骤7。接下来的几个小时我会花在限制懒惰上,如果有必要的话,我会学习

    作为一般指南:

  • 个人资料
  • 真正开始分析,就像真实的;-)
  • 删除反射(看起来像是您这样做的)
  • 将操作拆分为易于思考的函数
  • 消除惰性(传感器应为本部分的最后一步)
  • 使用loop/recur组合步骤,使您的代码无法理解,并且速度稍快(出于某种原因,这是最后一步)
  • 具体考虑您发布的代码:

    乍一看,这个函数将花费大量时间在for循环中生成一个值的惰性列表,然后立即实现(评估为不再是惰性的),因此生成该结构所花费的时间被浪费了。你可以考虑改变它来直接产生向量,<代码> MAPV是有用的。 第二部分是为每一行调用
    map
    in,这将产生大量中间数据结构。您可以考虑使用一个非懒惰的表达式,如<代码> MAVV<代码>或<代码>循环<代码> />代码> ReCurr> <代码> .<
    看起来您已经完成了步骤2-4,并且没有明显的理由跳到步骤7。接下来的几个小时我会花在限制懒惰上,如果有必要的话,我会学习

    你分析代码了吗?如果这个函数最初只需要0.1毫秒就可以在程序的整个生命周期内运行,那么16倍的加速是毫无意义的,从微观角度看,它只占总数的一小部分。您优化了瓶颈所在的位置—cpu将大部分时间用于执行任务的位置。您分析了代码吗?如果这个函数最初只需要0.1毫秒就可以在程序的整个生命周期内运行,那么16倍的加速是毫无意义的,从微观角度看,它只占总数的一小部分。您可以优化瓶颈所在的位置—cpu将大部分时间用于执行任务的位置。感谢您的指导!我得花一天时间熟悉传感器。我分析了代码,据我所知,大部分工作都在clojure.lang名称空间中。谢谢@marc b谢谢你的指导!我得花一天时间熟悉传感器。我分析了代码,据我所知,大部分工作都在clojure.lang名称空间中。谢谢@marc-b