簡體   English   中英

嘗試比較lib的性能以將InputStream復制到OutputStream

[英]Trying to compare performance of lib to copy an InputStream to an OutputStream

我想比較Guava和Apache Commons IO,將InputStream復制到OutputStream:

我比較了(同時啟動2個線程和CyclicBarrier )的速度:

  • org.apache.commons.io.IOUtils.copy
  • com.google.common.io.ByteStreams.copy

在4Go大小的文件上,結果完全相同,這是我的問題,除了后面的代碼完全相同或其他原因外,我不知道這是怎么可能的,但老實說,我認為我的問題出了點測試班?

結果

all threads started
commonsIo perf:PT6M21.281S
Guava perf:PT6M21.282S

碼:

public class Test {
    public static void main(String... a) throws InterruptedException, BrokenBarrierException {
        final CyclicBarrier gate = new CyclicBarrier(3);

        Thread t1 = new Thread() {
            public void run() {
                try {
                    gate.await();
                    Instant start = Instant.now();
                    IOUtils.copy(Files.newInputStream(Paths.get("C:\\Users\\emil.brigand\\Downloads\\CentOS-6.4-x86_64-bin-DVD1.iso")), Files.newOutputStream(Paths.get("C:\\Users\\emil.brigand\\Downloads\\CentOS-6.4-x86_64-bin-DVD12.iso"), StandardOpenOption.CREATE_NEW, StandardOpenOption.DELETE_ON_CLOSE));
                    Instant end = Instant.now();
                    System.out.println("commonsIo perf:" + Duration.between(start, end));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        };
        Thread t2 = new Thread() {
            public void run() {
                try {
                    gate.await();
                    Instant start = Instant.now();
                    ByteStreams.copy(Files.newInputStream(Paths.get("C:\\Users\\emil.brigand\\Downloads\\CentOS-6.4-x86_64-bin-DVD1.iso")), Files.newOutputStream(Paths.get("C:\\Users\\emil.brigand\\Downloads\\CentOS-6.4-x86_64-bin-DVD11.iso"), StandardOpenOption.CREATE_NEW, StandardOpenOption.DELETE_ON_CLOSE));
                    Instant end = Instant.now();
                    System.out.println("Guava perf:" + Duration.between(start, end));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        };
        t1.start();
        t2.start();
        gate.await();
        System.out.println("all threads started");
    }
}

您的基准測試不是很詳細,您可以考慮“如何在Java中編寫正確的微基准測試”中找到的信息以獲取詳細信息,但是在這種情況下,這無關緊要。

復制這么大的文件時,實際上並沒有相關的性能差異,因為I / O速度將勝過一切。 此外,在兩種情況下,您都使用InputStream進行文件復制操作這一事實同樣無效。

這意味着必須將數據從I / O緩沖區復制到Java字節數組中,然后再復制回來。 從Java 1.4開始,還有一個替代方法FileChannel.transferTo ,它告訴基礎系統直接傳輸字節而不復制到Java字節數組。

但是,由於您使用的是PathFiles ,因此您至少使用Java 7,因此可以簡單地使用Files.copy(Path,Path,…)而無需使用任何第三方庫,也無需繞開InputStream / OutputStream API 。 當然,它將利用NIO API的直接復制功能。

但是,即使使用此API,經過的時間也可能不會改變,因為I / O速度超過了這一切。 您不能通過重新排列程序代碼來加快硬盤等的速度。 與CPU速度相比,該硬件速度非常慢,如果有的話,CPU可以彌補軟件中的許多低效率。

盡管如此, Files.copy更易於使用,並且消除了對第三方庫的依賴,因此比較這些第三方庫的性能毫無意義……

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM