我的代码需要取0到255之间的整数值,并将其作为字符串写入文件。它需要很快,因为它可以非常快速地重复调用,因此任何优化在重负载时都会变得明显。此处还有其他问题涉及将大量数据量写入文件的有效方法,但少量数据如何?
这是我目前的做法:
public static void writeInt(final String filename, final int value)
{
try
{
// Convert the int to a string representation in a byte array
final String string = Integer.toString(value);
final byte[] bytes = new byte[string.length()];
for (int i = 0; i < string.length(); i++)
{
bytes[i] = (byte)string.charAt(i);
}
// Now write the byte array to file
final FileOutputStream fileOutputStream = new FileOutputStream(filename);
fileOutputStream.write(bytes, 0, bytes.length);
fileOutputStream.close();
}
catch (IOException exception)
{
// Error handling here
}
}
我不认为BufferedOutputStream
会对此有所帮助:构建刷新缓冲区的开销可能适用于3字符写入,不是吗?我可以做出任何其他改进吗?
答案 0 :(得分:5)
我认为考虑到0-255范围要求的要求,这个效率非常高。使用缓冲的写入器效率会降低,因为它会创建一些临时结构,您不需要使用这么少的字节来创建它们。
static byte[][] cache = new byte[256][];
public static void writeInt(final String filename, final int value)
{
// time will be spent on integer to string conversion, so cache that
byte[] bytesToWrite = cache[value];
if (bytesToWrite == null) {
bytesToWrite = cache[value] = String.valueOf(value).getBytes();
}
FileOutputStream fileOutputStream = null;
try {
// Now write the byte array to file
fileOutputStream = new FileOutputStream(filename);
fileOutputStream.write(bytesToWrite);
fileOutputStream.close();
} catch (IOException exception) {
// Error handling here
} finally {
if (fileOutputStream != null) {
fileOutputStream.close()
}
}
}
答案 1 :(得分:3)
你不能让它更快IMO。如果不是这样,BufferedOutputStream在这里没有任何帮助。如果我们查看src,我们将看到FileOutputStream.write(byte b [],int off,int len)将字节数组直接发送到本机方法,而BufferedOutputStream.write(byte b [],int off,int len)是首先将数组同步并复制到其缓冲区,并在关闭时将字节从缓冲区刷新到实际流。
除了这种情况下最慢的部分是打开/关闭文件。
答案 2 :(得分:0)
我认为,这里的瓶颈是IO,这两项改进可能会有所帮助:
Channel
而不是InputStream
。答案 3 :(得分:0)
抱歉这么晚来参加派对:)
我认为尝试优化代码可能不是正确的方法。如果您反复编写相同的小文件,并且每次都必须编写它而不是在应用程序中缓冲它,那么到目前为止,最重要的考虑因素是文件系统和存储硬件。
重点是,如果你每次都真的碰到硬件,那么你会严重打扰它。但是,如果你的系统正在缓存写入,那么你可能根本不会经常访问硬件:数据在到达之前就会被覆盖,只会写入新数据。
但这取决于两件事。首先,你的文件系统在它写入旧文件之前获得新写入时会做什么?某些文件系统可能仍然最终在日志中写入额外的条目,甚至将旧文件写入一个位置,然后将新文件写入不同的物理位置。那将是一个杀手。
另一方面,当被要求覆盖某些内容时,您的硬件会做什么?如果它是传统的硬盘驱动器,它可能只会覆盖旧数据。如果它是闪存(因为它可能是Android),那么磨损均衡将会启动,并且它会继续写入驱动器的不同位。
在磁盘缓存和文件系统方面,您确实需要做任何事情,以确保如果在将缓存推送到磁盘之前发送1000次更新,则只会写入最后一次更新。
由于这是Android,您可能正在查看ext2 / 3/4。仔细查看日志选项,并研究ext4中延迟分配的影响。也许最好的选择是使用ext4,但关闭日记。
答案 4 :(得分:-1)
快速谷歌搜索提出了各种大小的文件的不同写/读操作的基准:
http://designingefficientsoftware.wordpress.com/2011/03/03/efficient-file-io-from-csharp/
作者得出的结论是WinFileIO.WriteBlocks
在将数据写入文件方面表现最快,尽管I / O操作严重依赖于多种因素,例如操作系统文件缓存,文件索引,磁盘碎片,文件系统缓存等