この場合、reduceがrecurよりもはるかに最適ではないのはなぜですか?

sof

多項式の合計でπを計算する直感的な方法の1つは、次のようになります。

π=(1 / 1-1 / 3 + 1 / 5-1 / 7 + 1/9 ...)×4

次の関数ρまたはρ 'は多項式の合計を示し、πを計算するために消費された時間τがそれぞれ測定されます。

 (defn term [k]                                                                                                        
   (let [x (/ 1. (inc (* 2 k)))]                                                                                       
     (if (even? k)                                                                                                     
       x                                                                                                               
       (- x))))                                                                                                        

 (defn ρ [n]                                                                                                           
   (reduce                                                                                                             
     (fn [res k] (+ res (term k)))                                                                                     
     0                                                                                                                 
     (lazy-seq (range 0 n))))                                                                                          

 (defn ρ' [n]                                                                                                          
   (loop [res 0 k 0]                                                                                                   
     (if (< k n)                                                                                                       
       (recur (+ res (term k)) (inc k))                                                                                
       res)))                                                                                                          

 (defn calc [P]                                                                                                        
   (let [start (System/nanoTime)                                                                                       
         π (* (P 1000000) 4)                                                                                           
         end (System/nanoTime)                                                                                         
         τ (- end start)]                                                                                              
     (printf "π=%.16f τ=%d\n" π τ)))                                                                                   

 (calc ρ)                                                                                                              
 (calc ρ')       

結果は、したがって、基礎となるρは、ρ」よりも費やした半分以上の時間程度であることを告げる減らすよりもはるかに次善の行いをRECURこのケースが、なぜ?

アラン・トンプソン

コードを書き直し、より正確なタイマーを使用すると、大きな違いはありません。両方とも非常に基本的な形式であり、両方ともかなり最適化されているloop/recur予想されるため、これは予想さreduceれることです。

(ns tst.demo.core
  (:use demo.core tupelo.core tupelo.test)
  (:require
    [criterium.core :as crit] ))

(def result (atom nil))

(defn term [k]
  (let [x (/ 1. (inc (* 2 k)))]
    (if (even? k)
      x
      (- x))))

(defn ρ [n]
  (reduce
    (fn [res k] (+ res (term k)))
    0
    (range 0 n)) )

(defn ρ' [n]
  (loop [res 0 k 0]
    (if (< k n)
      (recur (+ res (term k)) (inc k))
      res)) )

(defn calc [calc-fn N]
  (let [pi (* (calc-fn N) 4)]
    (reset! result pi)
    pi))

Criteriumを使用して、両方のアルゴリズムの実行時間を測定します

(defn timings
  [power]
  (let [N (Math/pow 10 power)]
    (newline)
    (println :-----------------------------------------------------------------------------)
    (spyx N)
    (newline)
    (crit/quick-bench (calc ρ N))
    (println :rho @result)
    (newline)
    (crit/quick-bench (calc ρ' N))
    (println :rho-prime N @result)
    (newline)))

そして、Nの10 ^ 2、10 ^ 4、および10 ^ 6の値に対してそれを試します。

(dotest
  (timings 2)
  (timings 4)
  (timings 6))

10 ^ 2の結果:

-------------------------------
   Clojure 1.10.1    Java 14
-------------------------------

Testing tst.demo.core

:-----------------------------------------------------------------------------
N => 100.0

Evaluation count : 135648 in 6 samples of 22608 calls.
             Execution time mean : 4.877255 µs
    Execution time std-deviation : 647.723342 ns
   Execution time lower quantile : 4.438762 µs ( 2.5%)
   Execution time upper quantile : 5.962740 µs (97.5%)
                   Overhead used : 2.165947 ns

Found 1 outliers in 6 samples (16.6667 %)
    low-severe   1 (16.6667 %)
 Variance from outliers : 31.6928 % Variance is moderately inflated by outliers
:rho 3.1315929035585537

Evaluation count : 148434 in 6 samples of 24739 calls.
             Execution time mean : 4.070798 µs
    Execution time std-deviation : 68.430348 ns
   Execution time lower quantile : 4.009978 µs ( 2.5%)
   Execution time upper quantile : 4.170038 µs (97.5%)
                   Overhead used : 2.165947 ns
:rho-prime 100.0 3.1315929035585537

10 ^ 4の結果:

:-----------------------------------------------------------------------------
N => 10000.0

Evaluation count : 1248 in 6 samples of 208 calls.
             Execution time mean : 519.096208 µs
    Execution time std-deviation : 143.478354 µs
   Execution time lower quantile : 454.389510 µs ( 2.5%)
   Execution time upper quantile : 767.610509 µs (97.5%)
                   Overhead used : 2.165947 ns

Found 1 outliers in 6 samples (16.6667 %)
    low-severe   1 (16.6667 %)
 Variance from outliers : 65.1517 % Variance is severely inflated by outliers
:rho 3.1414926535900345

Evaluation count : 1392 in 6 samples of 232 calls.
             Execution time mean : 431.020370 µs
    Execution time std-deviation : 14.853924 µs
   Execution time lower quantile : 420.838884 µs ( 2.5%)
   Execution time upper quantile : 455.282989 µs (97.5%)
                   Overhead used : 2.165947 ns

Found 1 outliers in 6 samples (16.6667 %)
    low-severe   1 (16.6667 %)
 Variance from outliers : 13.8889 % Variance is moderately inflated by outliers
:rho-prime 10000.0 3.1414926535900345

10 ^ 6の結果:

:-----------------------------------------------------------------------------
N => 1000000.0

Evaluation count : 18 in 6 samples of 3 calls.
             Execution time mean : 46.080480 ms
    Execution time std-deviation : 1.039714 ms
   Execution time lower quantile : 45.132049 ms ( 2.5%)
   Execution time upper quantile : 47.430310 ms (97.5%)
                   Overhead used : 2.165947 ns
:rho 3.1415916535897743

Evaluation count : 18 in 6 samples of 3 calls.
             Execution time mean : 52.527777 ms
    Execution time std-deviation : 17.483930 ms
   Execution time lower quantile : 41.789520 ms ( 2.5%)
   Execution time upper quantile : 82.539445 ms (97.5%)
                   Overhead used : 2.165947 ns

Found 1 outliers in 6 samples (16.6667 %)
    low-severe   1 (16.6667 %)
 Variance from outliers : 81.7010 % Variance is severely inflated by outliers
:rho-prime 1000000.0 3.1415916535897743

10 ^ 4および10 ^ 6の場合のrhoおよびrho-primeフリップフロップの時間に注意してください。いずれにせよ、2倍未満しか変化しないタイミングについてはあまり信じたり心配したりしないでください。


アップデート

すでに怠惰なlazy-seqので、元のコードでを削除しましたclojure.core/rangeまた、母関数への再帰呼び出しlazy-seqなしで使用されるのを見たことがありませんcons

clojure.core/range、私たちはドキュメントを持っています:

範囲

開始(包括的)から終了(排他的)までの怠惰な数のシーケンスをステップごとに返します。ここで、開始はデフォルトで0、ステップは1、終了は無限大です。stepが0に等しい場合、開始の無限シーケンスを返します。startがendと等しい場合、空のリストを返します。

ソースコードでは、clojure.coreのJavaimplを呼び出します。

  ([start end]
   (if (and (instance? Long start) (instance? Long end))
     (clojure.lang.LongRange/create start end)
     (clojure.lang.Range/create start end)))

&Javaコードは、チャンク化されていることを示しています。

    public class Range extends ASeq implements IChunkedSeq, IReduce {
      private static final int CHUNK_SIZE = 32;
      <snip>

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

この場合、mclappyが適用よりも遅いのはなぜですか?

この場合、「sed」が「awk」よりもはるかに高速でないのはなぜですか

cross_val_predictがKNeighborsClassifierに適合するよりもはるかに遅いのはなぜですか?

この場合、PythonがC ++よりも高速なのはなぜですか?

私の場合、ForループがMap、Reduce、Listの理解よりも速いのはなぜですか

同じ目的で使用した場合、.html()が.text()よりもはるかに高速なのはなぜですか?

なぜ<は!=よりもはるかに速いのですか?

このjQueryコードがこれよりもはるかに遅いのはなぜですか?

Matlabで。*演算子がスカラーの*よりも速い場合があるのはなぜですか?

このPerl正規表現で `\ s +`が `\ s \ s *`よりもはるかに速いのはなぜですか?

フラットパックがスナップよりもはるかに大きいのはなぜですか(少なくともOkularの場合)?

この場合、最も適切なコンストラクターが呼び出されないのはなぜですか?

sumがinject(:+)よりもはるかに速いのはなぜですか?

ボケがmatplotlibよりもはるかに遅いのはなぜですか

Airflow 1.10.12が1.10.10よりもはるかに遅いのはなぜですか?

Spark DataFrameがRDDよりもはるかに遅いのはなぜですか?

このMySQLINがWHEREORよりもはるかに長いのはなぜですか?

volatileキーワードが使用されている場合でも、コンパイラがstrncmp()による共有メモリの読み取りを最適化するのはなぜですか?

符号なしに変換する場合、標準では「最小の符号なし整数」が結果であると言われています。ここで「最も少ない」ことが重要なのはなぜですか。

Trueの場合が1の場合よりも遅いのはなぜですか?

この場合、「=>」割り当ては機能するのに「=」は機能しないのはなぜですか?

OpenGLがポリゴンを切り取るのはなぜですか(この設定が無効になっている場合でも)?

この場合、場所が常にnullになるのはなぜですか?

ebxの値がeaxの値よりも大きい場合でも、コードがreturn1にジャンプするのはなぜですか

リストの最後に追加するときに、LinkedListがArrayListよりも遅いのはなぜですか?

この例では、For Eachループがlinqの外部結合よりも遅いのはなぜですか?

foreachを使用する場合よりもRforループが10倍遅いのはなぜですか?

なぜこのコードが間違っているのですか?'recur'はどのように機能しますか?

最適化(-O2、-O3)が使用されている場合、このコードの動作が異なるのはなぜですか?

TOP 一覧

  1. 1

    PictureBoxで画像のブレンドを無効にする

  2. 2

    レスポンシブウェブサイトの一番下にスティッキーなナビゲーションバーを作成するのに問題がある

  3. 3

    Rパッケージ「AppliedPredictiveModeling」のインストール中にエラーが発生しました

  4. 4

    Chromeウェブアプリのウェブビューの高さの問題

  5. 5

    HTTPヘッダー 'SOAPAction'の値はサーバーによって認識されませんでした

  6. 6

    Pythonを使用して、リストからデータを読み取り、特定の値をElasticsearchにインデックス付けするにはどうすればよいですか?

  7. 7

    C ++でのcURLとマルチスレッドの使用

  8. 8

    セレンのモデルダイアログからテキストを抽出するにはどうすればよいですか?

  9. 9

    tkinterウィンドウを閉じてもPythonプログラムが終了しない

  10. 10

    STSでループプロセス「クラスパス通知の送信」のループを停止する方法

  11. 11

    Spring @ModelAttributeモデルフィールドマッピング

  12. 12

    Python / SciPyのピーク検出アルゴリズム

  13. 13

    Ansibleで複数行のシェルスクリプトを実行する方法

  14. 14

    テキストフィールドの値に基づいて UIslider を移動します

  15. 15

    tf.nn_conv2dとtf.nn.depthwise_conv2dの違い

  16. 16

    ZScalerと証明書の問題により、Dockerを使用できません

  17. 17

    MLでのデータ前処理の背後にある直感

  18. 18

    Postmanを使用してファイル付きの(ネストされた)jsonオブジェクトを送信する

  19. 19

    java.lang.NoClassDefFoundError:com / sun / istack / tools / DefaultAuthenticator $ Receiver

  20. 20

    Windows 10 Pro 1709を1803、1809、または1903に更新しますか?

  21. 21

    BLOBストレージからデータを読み取り、Azure関数アプリを使用してデータにアクセスする方法

ホットタグ

アーカイブ