我正在尝试优化基于Web的应用程序,该应用程序会对流进行大量编写。 代码是这样的---
StringWriter stringWriter = new StringWriter(1024);
PrintWriter printWriter = new PrintWriter(stringWriter);
然后这个printwriter用于在几个地方做很多写操作,比如 -
printWriter.write("set interface ethernet0 zone Trust");
我想通过将printwriter包装在bufferedwriter周围来优化几个写操作。所以我打算如下更改line1和line2。如果下面的方法是正确的,请告诉我 -
StringWriter stringWriter = new StringWriter(1024);
// go for bufferedwriter instead of printwriter.
BufferedWriter bufWriter = new BufferedWriter(stringWriter, 8*1024);
另外,我认为现在我可以直接替换write方法,如 -
printWriter.write("set interface ethernet0 zone Trust");
替换为
bufWriter.write("set interface ethernet0 zone Trust");
如果这是正确的,请告诉我,或者我是否需要使用BufferedWriter的任何重载方法来充分利用BufferedWriter。
谢谢, 开发
答案 0 :(得分:11)
由于StringWriter
根据定义写入字符串缓冲区(在内存中),因此将其包装到BufferedWriter
中不会对性能产生任何影响。 (由于额外的间接级别,它实际上可能会使您的代码变慢 - 尽管这个 可能最有可能被JIT编译器优化掉。)< / p>
后者在文件I / O中很有用,其中一次大写比几次小写快得多。
为什么你认为你需要调整这段代码?值得仔细阅读以下内容
答案 1 :(得分:4)
添加BufferedWriter只会为每个写入的char添加额外的复制操作。你应该改变StringWriter的初始大小,更大的初始大小意味着更少的增长和更少的复制。
StringWriter本身包含一个不断增长的字符数据缓冲区,通过使用BufferedWriter在其上添加额外的缓冲区不会导致加速。从给定的代码中,StringWriter对象本身的较大初始大小可能会有所帮助。
答案 2 :(得分:3)
你真的需要使用StringWriter吗? StringWriter只是StringBuffer的一个代理,它会在每次调用append时自行同步。
您是否考虑过使用StringBuilder?它不是同步的(因此不是线程安全的),但应该更快 - 特别是如果你做了很多短写。
编辑:同步问题非常重要,因为PrintWriter也是同步的。每次调用print / write时,代码都必须获取并释放两个锁。我怀疑这可能就是为什么你的代码在write方法上花费了大量时间。
编辑: 如果你真的必须使用PrintWriter,那么下面的替代方案可以工作,但需要注意的是PrintWriter只能被一个线程访问 - 否则它可能会导致死锁。为了使这项工作顺利,所有写入必须在SAME同步块中执行,否则您将遇到同样的问题 - 例如进入和退出大量同步代码位。
ByteArrayOutputStream out = new ByteArrayOutputStream(bufSize);
PrintWriter writer = new PrintWriter(out);
synchronized (writer) {
// do writes
}
writer.flush(); // very important or you may not see any output in 'out'
writer.close();
String output = out.toString();
如果您不必使用PrintWriter,那么仅使用StringWriter即可。
StringWriter writer = new StringWriter(bufSize);
synchronized(writer.getBuffer()) {
// do writes
}
writer.flush();
writer.close();
String output = writer.toString();
我的初步建议意味着什么:
StringBuilder builder = new StringBuilder();
// do APPENDS (instead of writes)
String output = builder.toString();
你需要调用append而不是write,这就是你需要重构代码的原因。
答案 3 :(得分:0)
我真的怀疑BufferedWriter
会在这里给予任何性能提升 - 它和StringWriter
直接写入记忆。如果有的话,它会通过添加一个间接层来减慢(分数)的速度。当然,如果你发现不同,请纠正我。是什么让你认为这是一个瓶颈?