gpt4 book ai didi

android - 为什么 Okio 比 BufferedInputStream 和 BufferedOutputStream 更高效?

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:41:24 25 4
gpt4 key购买 nike

我试图找出为什么 OkHttp 使用 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();
}

我调用了 5 次 bufferedIO(),结果是:

357ms
299ms
311ms
324ms
331ms

我调用了 okio() 5 次,结果是:

524ms
661ms
555ms
525ms
573ms

从结果来看,BufferedInputStream 和 BufferedOutputStream 比 Okio 效率更高。我的验证有问题吗?

最佳答案

我在桌面上运行了这个基准测试,结果非常不一致。我认为基准测试最终衡量的是文件系统性能,而不是 I/O 库。

我去掉了 Okio 基准测试中的额外间接寻址,从 Source 而不是中间的 FileInputStream 开始。我还删除了 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。如果您想尝试一下,我对结果很感兴趣!

关于android - 为什么 Okio 比 BufferedInputStream 和 BufferedOutputStream 更高效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44904083/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com