2017-07-04 14 views
4

OkHttpがOkioを使用する理由を調べようとしましたが、BufferedInputStreamとBufferedOutputStreamはデータをバッファしません。 Iを確認するために、次のコードを使用する:OkioはなぜBufferedInputStreamとBufferedOutputStreamよりも効率的ですか?

private String targetPath = Environment.getExternalStorageDirectory() 
     + File.separator + "performance.dat"; 

private InputStream getInputStream() { 
    try { 
     File targetFile = new File(targetPath); 

     if (targetFile.exists()) { 
      targetFile.delete(); 
     } 

     targetFile.createNewFile(); 
     return new FileInputStream("/sdcard/file.zip"); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    return null; 
} 

public void bufferedIO(View view) { 
    new Thread() { 

     @Override 
     public void run() { 
      InputStream inputStream = getInputStream(); 

      if (inputStream == null) { 
       return; 
      } 

      long start = System.currentTimeMillis(); 

      inputStream = new BufferedInputStream(inputStream, 8192); 
      File targetFile = new File(targetPath); 
      BufferedOutputStream fileOutputStream = null; 

      try { 
       fileOutputStream = new BufferedOutputStream(new FileOutputStream(targetFile, true), 8192); 
       byte[] buffer = new byte[4096]; 

       int count; 
       while ((count = inputStream.read(buffer)) > 0) { 
        fileOutputStream.write(buffer, 0, count); 
       } 

       fileOutputStream.flush(); 
       Log.i("performance", "BufferedInputStream and BufferedOutputStream: " + (System.currentTimeMillis() - start) + "ms"); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } finally { 
       try { 
        inputStream.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 

       if (fileOutputStream != null) { 
        try { 
         fileOutputStream.close(); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
     } 
    }.start(); 
} 

public void okio(View view) { 
    new Thread() { 

     @Override 
     public void run() { 
      InputStream inputStream = getInputStream(); 

      if (inputStream == null) { 
       return; 
      } 

      long start = System.currentTimeMillis(); 

      File targetFile = new File(targetPath); 
      Source bufferSource = Okio.buffer(Okio.source(inputStream)); 
      BufferedSink bufferSink = null; 

      try { 
       bufferSink = Okio.buffer(Okio.sink(targetFile)); 

       while ((bufferSource.read(bufferSink.buffer(), 4096)) != -1) { 
        bufferSink.emitCompleteSegments(); 
       } 
       bufferSink.flush(); 

       Log.i("performance", "okio: " + (System.currentTimeMillis() - start) + "ms"); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } finally { 
       try { 
        bufferSource.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 

       if (bufferSink != null) { 
        try { 
         bufferSink.close(); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
     } 
    }.start(); 
} 

Iは(bufferedIOという)5回、結果は次のとおり

357ms 
299ms 
311ms 
324ms 
331ms 

私は(okio呼ばれる)5回、結果は次のとおり

524ms 
661ms 
555ms 
525ms 
573ms 

結果によると、BufferedInputStreamとBufferedOutputStreamはOkioより効率的です。私の検証に何か問題はありますか?

答えて

2

私はデスクトップ上でこのベンチマークを実行しましたが、私の結果は非常に矛盾していました。ベンチマークは最終的にはI/Oライブラリよりもファイルシステムのパフォーマンスを測るものだと私は思う。

Okioのベンチマークでは、中間のFileInputStreamではなく、Sourceで始まる余分な間接指定を取り出しました。私はまた、Okioのために必要ではないページごとのループを削除:あなただけのシンクに全体のソースをコピーしwriteAll()を呼び出すことができます。

public void okio() throws IOException { 
    long start = System.currentTimeMillis(); 

    File targetFile = new File(targetPath); 
    targetFile.delete(); 

    try (BufferedSink sink = Okio.buffer(Okio.sink(targetFile)); 
     Source bufferSource = Okio.source(new File(sourcePath))) { 
    sink.writeAll(bufferSource); 
    System.out.println("okio: " + (System.currentTimeMillis() - start) + "ms"); 
    } 
} 

私の結果が原因ファイルシステムのパフォーマンスに乱暴に矛盾していました - 個々のランは200%以上変化した。

okio: 67ms java.io: 106ms 
okio: 98ms java.io: 106ms 
okio: 108ms java.io: 110ms 
okio: 121ms java.io: 113ms 
okio: 125ms java.io: 116ms 
okio: 131ms java.io: 118ms 
okio: 143ms java.io: 143ms 
okio: 154ms java.io: 145ms 
okio: 191ms java.io: 146ms 
okio: 217ms java.io: 239ms 

ここでは全体的にOkioが効率的でしたが、それはちょうど運が良いかもしれません。より良いベンチマークは、信頼できないファイルシステムI/Oを分離するでしょう。それを試したいのであれば、結果に興味があります!

0

私はそれが以前よりもはるかに高速になりますが、私はなぜわからない

Source bufferSource = null; 
try { 
     bufferSource = Okio.buffer(Okio.source(targetFile)); 
} catch (Exception e) { 
     e.printStackTrace(); 
} 

Source bufferSource = Okio.buffer(Okio.source(inputStream)); 

からあなたのコードを変更しました。 okioのソースコードを確認する時間が必要です。

関連する問題