简体   繁体   English

Okio 与 java.io 的性能对比

[英]Okio vs java.io performance

I read the following blog: https://medium.com/@jerzy.chalupski/a-closer-look-at-the-okio-library-90336e37261我阅读了以下博客: https ://medium.com/@jerzy.chalupski/a-closer-look-at-the-okio-library-90336e37261

It is said that" the Sinks and Sources are often connected into a pipe. Smart folks at Square realized that there's no need to copy the data between such pipe components like the java.io buffered streams do. All Sources and Sinks use Buffers under the hood, and Buffers keep the data in Segments, so quite often you can just take an entire Segment from one Buffer and move it to another."据说“Sinks 和 Sources 经常连接成一个管道。Square 的聪明人意识到没有必要像 java.io 缓冲流那样在管道组件之间复制数据。所有 Sources 和 Sinks 都在引擎盖,而 Buffers 将数据保存在 Segments 中,所以通常你可以从一个 Buffer 中取出整个 Segment 并将其移动到另一个。”

I just dont understand where is the copy of data in java.io.我只是不明白 java.io 中的数据副本在哪里。

And in which case a Segment would be moved to another Buffer.在这种情况下,Segment 将被移动到另一个 Buffer。

After i read source code of Okio.在我阅读了 Okio 的源代码之后。 If writing strings to file by Okio like the following:如果通过 Okio 将字符串写入文件,如下所示:

val sink = logFile.appendingSink().buffer()
sink.writeUtf8("xxxx")

there will be no "moving segment to another Buffer".不会有“将段移动到另一个缓冲区”。 Am i right?我对吗?

Java's BufferedReader is just a Reader that buffers data into a buffer – the buffer being a char[] , or something like that – so that every time you need a bunch of bytes/chars from it, it doesn't need to read bytes from a file/network/whatever your byte source is (as long as it has buffered enough bytes). Java 的BufferedReader只是一个将数据缓冲到缓冲区中的Reader ——缓冲区是一个char[]或类似的东西——所以每次你需要从中获取一堆字节/字符时,它不需要从中读取字节文件/网络/无论您的字节源是什么(只要它缓冲了足够的字节)。 A BufferedWriter does the opposite operation: whenever you write a bunch of bytes to the BufferedWriter , it doesn't actually write bytes to a file/socket/whatever, but it "parks" them into a buffer, so that it can flush the buffer only once it's full. BufferedWriter执行相反的操作:每当您将一堆字节写入BufferedWriter时,它实际上并没有将字节写入文件/套接字/其他任何东西,而是将它们“停放”到缓冲区中,以便它可以flush缓冲区只有一次满了。 Overall, this minimises access to file/network/whatever, as it could be expensive.总体而言,这最大限度地减少了对文件/网络/任何东西的访问,因为它可能很昂贵。

When you pipe a BufferedReader to a BufferedWriter , you effectively have 2 buffers.当您通过管道将BufferedReader传递给BufferedWriter时,您实际上有 2 个缓冲区。 How does Java move bytes from one buffer to the other? Java 如何将字节从一个缓冲区移动到另一个缓冲区? It copies them from the source to the sink using System.arraycopy (or something equivalent).它使用System.arraycopy (或等效的东西)将它们从源复制到接收器。 Everything works well, except that copying a bunch of bytes requires an amount of time that grows linearly as the size of the buffer(s) grow.一切都很好,除了复制一堆字节需要随着缓冲区大小的增长而线性增长的时间。 Hence, copying 1 MB will take roughly 1000 times more than copying 1 KB.因此,复制 1 MB 所需的时间大约是复制 1 KB 的 1000 倍。

Okio, on the other hand, doesn't actually copy bytes.另一方面,Okio 实际上并不复制字节。 Oversimplifying the way how it works, Okio has a single byte[] with the actual bytes, and the only thing that gets moved from the source to the sink is the pointer (or reference) to that byte[] , which requires the same amount of time regardless of its size.过度简化它的工作方式,Okio 有一个带有实际字节的byte[] ,唯一从源移动到接收器的是指向该byte[]的指针(或引用),这需要相同的数量时间不管它的大小。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM