2017-03-16 113 views
0

我試圖從輸入流中讀取字節,它比讀取字符要慢得多。我無法弄清楚爲什麼會這樣。看看測試:Clojure:輸入流比讀取器慢

(defn r1 
    [input] 
    (loop [] 
    (when-not (= -1 (.read ^java.io.InputStream input)) 
     (recur)))) 

(defn r2 
    [input] 
    (loop [] 
    (when-not (.read input) 
     (recur)))) 

(dotimes [_ 10] 
    (time (with-open [is (clojure.java.io/input-stream "15mb.log")] 
    (r1 is)))) 

"Elapsed time: 111.608991 msecs" 
"Elapsed time: 95.45663 msecs" 
"Elapsed time: 148.789867 msecs" 
"Elapsed time: 97.580527 msecs" 
"Elapsed time: 113.093759 msecs" 
"Elapsed time: 108.306019 msecs" 
"Elapsed time: 107.71069 msecs" 
"Elapsed time: 104.833343 msecs" 
"Elapsed time: 174.701027 msecs" 
"Elapsed time: 141.969629 msecs" 

(dotimes [_ 10] 
    (time (with-open [r (clojure.java.io/reader "15mb.log")] 
     (r2 r)))) 

"Elapsed time: 0.635769 msecs" 
"Elapsed time: 0.422315 msecs" 
"Elapsed time: 0.355953 msecs" 
"Elapsed time: 0.336128 msecs" 
"Elapsed time: 0.333523 msecs" 
"Elapsed time: 0.339613 msecs" 
"Elapsed time: 0.329693 msecs" 
"Elapsed time: 0.234213 msecs" 
"Elapsed time: 0.209742 msecs" 
"Elapsed time: 0.199334 msecs" 

據我所知clojure.java.io/input-stream使用的BufferedInputStream和clojure.java.io/reader使用的BufferedReader因此沒有理由在速度如此的顯着的差異。我想念什麼?

+1

你確定你的'r2'是正確的?你沒有在那裏使用'.readLine'嗎? (測試結果是否是虛假的,而不是將其與-1進行比較會顯示它) –

+0

是的,r2不正確。謝謝。 –

回答

1

您的測試存在缺陷。在流的末尾,BufferedReaderBufferedInputStream都返回-1。所以,您對r2的測試也應該是(when-not (= -1 (.read ...

雖然下面的測試方法不準確到很小的毫秒級別,但對於此測試來說足夠準確,而使用非常好的clojure基準庫進行的測試會得到類似的結果。再次發佈測試更加緊湊,便於複製/粘貼:

(let [testfile "zerofile"] ; $ dd if=/dev/zero of=zerofile bs=1k count=1k 
    (map (fn [func label] 
     (println label) 
     (dotimes [_ 3] 
      (time (with-open [data (func testfile)] 
        (while (not= -1 (.read data))))))) 
    [clojure.java.io/input-stream, clojure.java.io/reader] 
    ["Input Stream:" "\nReader:"])) 

一個結果:

Input Stream: 
"Elapsed time: 624.01494 msecs" 
"Elapsed time: 650.407183 msecs" 
"Elapsed time: 627.244097 msecs" 

Reader: 
"Elapsed time: 706.776733 msecs" 
"Elapsed time: 691.887275 msecs" 
"Elapsed time: 703.918226 msecs" 
+0

感謝您的幫助,我現在看到了。在我的例子中,我很快就會帶着讀者離開。 –