2016-08-08 25 views
0

Es scheint eine große Sache zu sein, aber gibt es irgendwelche signifikanten Unterschiede in den folgenden 3 Methoden zum Zählen der Anzahl der wahren Gegenstände?Unterschied zwischen 3 Methoden der Erkennung von True in Racket

Sie alle produzieren identische Ergebnisse, aber gibt es einen Grund, warum eine bestimmte sollte oder nicht gewählt werden?

Edit: zur Verwendung von Zeitfunktion werden folgende Ergebnisse mit 3 Funktionen erhalten oben und je 2 aus Antworten von @ ChrisJester-Young und @Sylwester:

"---------- 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 

Daher ist die „count Lambda“ Methode der am schnellsten.

+0

Ich könnte sagen, das Lambda wäre der beste Weg zu gehen, weil es am einfachsten zu lesen ist (zu mir) ... Aber Sie sollten versuchen (Zeit (counttrue ...)), um zu sehen, welche in Leistung – Matthew

+0

übertrifft Was ist deine Vermutung? – rnso

+0

Ich glaube, das Lambda ist am schnellsten – Matthew

Antwort

3

Die count Version ist wahrscheinlich die idiomatische (außer ich würde es als (count identity items) schreiben). Außerdem ist die set! Version definitiv kein idiomatischer Schläger, und Racket optimiert nicht seine Verwendung, wie Sie aus Ihren Zeittests sehen können.

Hier sind ein paar Alternativen für Ihr Timing Vergnügen:

  1. for Comprehensions Verwendung:

    (for/sum ((x (in-list items)) #:when x) 1) 
    
  2. Handbuch Looping:

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

Ich habe Ihre Funktionen in die Timing-Informationen in meiner Frage aufgenommen. – rnso

2

Sie sind einfach anders Wege, das Gleiche zu tun. Alle von ihnen sind O (n), also unterscheiden sie sich nicht viel in der Zeit. Einige von ihnen verschwenden eine kleine Erinnerung, indem sie eine Zwischenliste haben, aber ich denke, Sie haben mehr Zeit damit verschwendet, diese zu vergleichen, als Sie jemals zurückkommen werden, indem Sie den schnellsten auswählen. Ich würde für den einen gehen, die kürzeste und auf den Punkt, bezogen auf Ihre dritte:

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

Es ist eigentlich nur eine spezialisierte foldl:

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

Beide count und foldl sind mit dem Namen implementiert let in #!racket.