从内存读取就像从磁盘读取一样?
Read from memory as read from disk?
有没有一种方法可以将内存读取视为磁盘读取?问题是,我想测试如果我直接从内存读取和处理文件的相同内容,与在磁盘 I/O 上相比,性能提升多少。但是我的代码是以从磁盘 I/O 读取的方式编写的(例如打开文件、从文件读取和关闭文件)。如果有办法我们可以将文件推送到本地内存并将内存块视为要处理的文件,那就太好了。任何直接的解决方案都会受到赞赏。
顺便说一句,在 Linux 上使用 Java/Python。 :)
如果我没理解错的话,您更感兴趣的是将文件加载到内存中然后对其进行解析,例如,而不是将文件实际存储在内存(RAM 磁盘)中。
您可以在 Java 和 Python 中执行此操作。例子:
http://rosettacode.org/wiki/Read_entire_file#Python。您甚至可以编写接受文件流或直接从内存读取的其他类型流的函数,让函数的调用者决定如何检索数据。
但是,这种首先将整个文件(或大块)读取到内存然后处理内存的间接方式很少会给您带来任何实际收益。原因之一是因为虽然磁盘 I/O 是 真的很慢,但大多数 languages/libraries 中的 I/O 流无论如何都会缓冲读取文件。所以他们已经在为你做这件事了。
文件 I/O 操作的成本经常被高估,而处理文件所涉及的逻辑却被低估。因此,我认为值得分析您的代码以查看 disk I/O 是否真的是罪魁祸首。探查器不仅可以让您知道,还可以告诉您到底是什么罪魁祸首。
如果您不打算在服务之前修改文件内容(例如 decoding/compression),为什么不利用零拷贝 NIO transferTo 和 transferFrom 方法将文件直接发送到套接字,甚至无需跨用户边界和在内核级别做。
final File inputFile = new File(args[0]);
FileInputStream fileInputStream = new FileInputStream(inputFile);
FileChannel fileChannel = fileInputStream.getChannel();
SocketAddress socketAddress = new InetSocketAddress("localhost", 8083);
SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(socketAddress);
long totalBytesTransferred = 0;
while (totalBytesTransferred < inputFile.length()) {
long bytesTransferred = fileChannel.transferTo(totalBytesTransferred, inputFile.length()-totalBytesTransferred, socketChannel);
totalBytesTransferred += bytesTransferred;
}
零拷贝在 Linux 上可用,它的速度提高了 2 倍,内存占用更少。
有没有一种方法可以将内存读取视为磁盘读取?问题是,我想测试如果我直接从内存读取和处理文件的相同内容,与在磁盘 I/O 上相比,性能提升多少。但是我的代码是以从磁盘 I/O 读取的方式编写的(例如打开文件、从文件读取和关闭文件)。如果有办法我们可以将文件推送到本地内存并将内存块视为要处理的文件,那就太好了。任何直接的解决方案都会受到赞赏。
顺便说一句,在 Linux 上使用 Java/Python。 :)
如果我没理解错的话,您更感兴趣的是将文件加载到内存中然后对其进行解析,例如,而不是将文件实际存储在内存(RAM 磁盘)中。
您可以在 Java 和 Python 中执行此操作。例子: http://rosettacode.org/wiki/Read_entire_file#Python。您甚至可以编写接受文件流或直接从内存读取的其他类型流的函数,让函数的调用者决定如何检索数据。
但是,这种首先将整个文件(或大块)读取到内存然后处理内存的间接方式很少会给您带来任何实际收益。原因之一是因为虽然磁盘 I/O 是 真的很慢,但大多数 languages/libraries 中的 I/O 流无论如何都会缓冲读取文件。所以他们已经在为你做这件事了。
文件 I/O 操作的成本经常被高估,而处理文件所涉及的逻辑却被低估。因此,我认为值得分析您的代码以查看 disk I/O 是否真的是罪魁祸首。探查器不仅可以让您知道,还可以告诉您到底是什么罪魁祸首。
如果您不打算在服务之前修改文件内容(例如 decoding/compression),为什么不利用零拷贝 NIO transferTo 和 transferFrom 方法将文件直接发送到套接字,甚至无需跨用户边界和在内核级别做。
final File inputFile = new File(args[0]);
FileInputStream fileInputStream = new FileInputStream(inputFile);
FileChannel fileChannel = fileInputStream.getChannel();
SocketAddress socketAddress = new InetSocketAddress("localhost", 8083);
SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(socketAddress);
long totalBytesTransferred = 0;
while (totalBytesTransferred < inputFile.length()) {
long bytesTransferred = fileChannel.transferTo(totalBytesTransferred, inputFile.length()-totalBytesTransferred, socketChannel);
totalBytesTransferred += bytesTransferred;
}
零拷贝在 Linux 上可用,它的速度提高了 2 倍,内存占用更少。