2016-08-08 12 views
0

実際のアイテム数をカウントする3つの方法に大きな違いはありますか?ラケットで真を検出する3つの方法の違い

これらはすべて同じ結果をもたらしますが、特定のものを選択する必要がある理由は何か?

編集:時間関数を使用して、以下の結果が@ ChrisJester・ヤングと@Sylwesterによって回答から3つの上記機能及び2それぞれで得られる:

したがって
"---------- counttrue ------------" 
cpu time: 751 real time: 751 gc time: 16 
"---------- counttrue2 ------------" 
cpu time: 946 real time: 947 gc time: 10 
"---------- counttrue3 ------------" 
cpu time: 456 real time: 457 gc time: 8 
"---------- counttrue_chris1 ------------" 
cpu time: 726 real time: 727 gc time: 9 
"---------- counttrue_chris2 ------------" 
cpu time: 595 real time: 595 gc time: 8 
"---------- counttrue_sylwester1 ------------" 
cpu time: 543 real time: 544 gc time: 7 
"---------- counttrue_sylwester2 ------------" 
cpu time: 515 real time: 515 gc time: 7 

、「カウントラムダ」法であります最速

+0

私はラムダが(私に)読むのが最も簡単なので、ラムダが行く最善の方法だと言えるかもしれません...しかし、あなたがパフォーマンスに優れているかを見るために(時間(counttrue ...))試してください – Matthew

+0

あなたの推測は? – rnso

+0

私はラムダが最も速いと信じます – Matthew

答えて

3

おそらくcountバージョンが最も慣用的です(私は(count identity items)と書いています)。さらに、set!バージョンは間違いなく慣用的なラケットではなく、ラケットはそのタイミングテストからわかるように、その使用を最適化しません。ここで

は、あなたのタイミングの喜びのための選択肢のカップルです:

  1. for内包表記の使用:

    (for/sum ((x (in-list items)) #:when x) 1) 
    
  2. マニュアルループ:

    (let loop ((sum 0) 
          (items items)) 
        (cond ((null? items) sum) 
         ((car items) (loop (add1 sum) (cdr items))) 
         (else (loop sum (cdr items))))) 
    
+0

私はあなたの機能を私の質問のタイミング情報に含めました。 – rnso

2

を彼らはただですdiffe同じことをする方法を借りる。彼らはすべてO(n)なので、時間的にはあまり変わらない。彼らの中には中級者リストを持つことで少しの記憶を浪費している人もいますが、最も速いものを選んで戻ってくるよりも時間を無駄にしてしまったと思います。私はあなたの第三に基づき、最短ポイントにある1のために行くだろう:

(define (count-true . args) 
    (count values args)) 

それは実際には、専門foldlのだ:

(define (count-true . args) 
    (foldl (lambda (val sum) 
      (if val (add1 sum) sum)) 
     0 
     args)) 

countfoldlの両方が命名して実装されているlet#!racketにあります。

関連する問題