6

我试图了解我从 MappedByteBuffer 类的 get() 方法获得的性能是否正常。我的代码如下:

private byte[] testBuffer = new byte[4194304];
private File sdcardDir, filepath;
private FileInputStream inputStream; 
private FileChannel fileChannel;
private MappedByteBuffer mappedByteBuffer;

// Obtain the root folder of the external storage
sdcardDir = Environment.getExternalStorageDirectory();

// Create the reference to the file to be read
filepath = new File(sdcardDir, "largetest.avi");
inputStream = new FileInputStream(filepath);
fileChannel = inputStream.getChannel();

mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, (4194304));

Log.d("GFXUnpack", "Starting to read");
mappedByteBuffer.position(0);
mappedByteBuffer.get(testBuffer, 0, (4194304));
Log.d("GFXUnpack", "Ended to read");
mappedByteBuffer.rewind();

由于我是初学者,并且我需要从 SD 卡读取数据的最快方法,因此我查找了文档,发现文件映射在许多情况下被认为是从文件中读取数据的最快方法。但是如果我运行上面的代码,虽然缓冲区被正确填充,但性能很慢(或者可能不是?你决定!!)我可以在近 5 秒内读取那些 4194304 字节,即每秒不到 1MB。我正在使用 Eclipse 直接连接到我的 Optimus Dual 智能手机;即使我将读取操作置于循环中,读取也需要相同的时间(如果执行多次读取,可能不会发生开销初始化......不是这种情况)。

如果我减小或增大文件,此文件大小与时间的关系不会改变:几乎 9 秒内将读取 8 兆,2 秒内将读取 2 兆,依此类推。我读过,即使是慢速 SD 卡也可以以每秒至少 5 MB 的速度读取......请注意,4194304 是 2 值的幂,因为我已经读过这会提高性能。请告诉我您的意见:现代智能手机的实际性能是每秒 1MB,还是我的代码有问题?谢谢

4

2 回答 2

3

在 Hotspot JVM 中,MappedByteBuffer.get() 使用内部调用而不是本机调用毫无价值。当复制大数据块时,它一次复制多个字节,例如使用 MMX 指令复制 8 个字节或更长。

AFAIK,Android 不这样做,这使得这个电话更加昂贵。

于 2012-11-20T13:07:06.223 回答
1

我看不出你的代码有什么问题。它可能只是设备和/或文件系统实现的速度。正如Tom Hawtin所说,“[m] 内存映射 I/O 不会使您的磁盘运行得更快”。

于 2012-11-20T13:02:39.090 回答