- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这是为 tomcat/网络专家准备的。我会对其进行基准测试/wireshark,但这要求很高,也许有人马上就知道答案。
比较这两种生成 servlet 输出的方法,从用户的角度来看,哪种方法最快:
直接写入 servlet 输出流:
for( int i=0; i<10000; i++ ) { servletOutputStream.write( "a"); /* 有一点延迟 */
创建一个buffer并一次性写入
for( int i=0; i<10000; i++ ) { stringbuffer.append( "a");}servletOutputStream.write( stringBuffer.toString() )
我可以想象方法 1 的优点是响应可以快速开始发送内容,而在方法 2 中发送会晚一些。
另一方面,方法 1 可以生成更多/更小的 TCP 数据包,这反过来可能需要更长的时间才能完全传输?
问候
PS:请不要告诉我这是过早的优化。在手头的例子中,我有一个同时提供 toString
和 write(Appendable a)
方法的对象。我只需要在这里选择使用哪一个。此外,从理论的角度和关于 servlet 的一般设计,我发现这非常有趣。
编辑:感谢大家的回答。但似乎我的问题不清楚或过于简化了我的示例。
我根本不担心没有缓冲。我知道在发送队列中至少有一个地方必须有缓冲。可能它在多个地方(Java、操作系统、硬件)。我认为我真正的问题是:这些缓冲区何时刷新?
因此,为了更清楚地说明,我们假设我们的 MTU 为 1000,并且连续数据包的发送是由硬件的缓冲区空中断触发的。那么在第一种情况下,它可能看起来像:
. packet( "a" ) //triggered by the first write( "a" ),
. packet( "aaaaaaa" ) // triggered by buffer-empty, sending the amount of "a"s which have been written in the meantime
. packet( "aaaa" ) // and so on
. packet( "aaaaaaaaaaa" )
...x1000 // or so in this example
而对于第二种情况,发送开始时所有 10000 个字节都已经可用,因此结果将是:
. packet( "aaaa....a(x1000)" )
. packet( "aaaa....a(x1000)" )
...x10
即使对于更小的数据大小(小于 MTU,比方说 100 个“a”)并且创建输出的速度更快,那么发送结果可能如下所示:
. packet( "a" ) // first write
. packet( "aaaa...a(x99) ) // all remaining data available when buffer-empty interrupt.
当然,如果缓冲区的工作方式不同,所有这一切都会完全不同。例如。如果他们正在等待更多数据发送或等待刷新发送任何东西......(但这反过来也会在某些方面减慢发送速度)
所以这是我不知道的:tomcat 中的缓冲到底是如何工作的,使用它的最佳策略是什么?
(我并不担心或期待更大的速度提升。我只是想知道事情是如何运作的。)
最佳答案
我希望 ServletOutputStream
实际上是一个实例
org.apache.tomcat.core.BufferedServletOutputStream
这是(顾名思义)是一个缓冲流。这意味着最好将字符直接写入流,而不是将它们组装到 StringBuffer
或 StringBuilder
中并写入结果。直接写至少会避免字符的复制。
如果发现您的 ServletOutputStream
还没有缓冲,那么您可以将其包装在 BufferedOutputStream
中,您将得到相同的结果。
假设现在您正在谈论流。 (刷新 StringBuffer
没有任何意义。)
When is are these buffers flushed?
当它们已满时,当您在流上调用 flush
时,或者当流关闭时。
... and what would be the the best strategy of using it?
一般情况下,写入数据,完成后关闭文件。不要显式刷新,除非有充分的理由这样做。如果您传送的是普通的 HTTP 响应,则很少见。 (刷新很容易导致网络堆栈通过发送更多网络数据包来传输相同数量的信息。这可能会影响整体网络吞吐量。)
在 servlet 框架的情况下,我记得 Servlet 规范说 ServletOutputStream
将在请求/响应处理完成时自动刷新并关闭。如果您没有包装 ServletOutputStream
,您甚至不需要关闭流。 (虽然它没有害处。)
关于java - Tomcat Servlet性能: StringBuilder vs.直接写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32758501/
公共(public)类TestMyStringBuilderII { public static void main(String[] args) { StringBuilder sb = n
我们都知道字符串是不可变的而StringBuilder是可变的。正确的。那么为什么它的方法会返回一个 StringBuilder 对象。它们不应该都是 void 方法吗? 为什么会这样 public
当我读到 equals() 方法用于比较 java 中的字符串是否相等但是当我运行这段代码时我得到输出 false 。为什么? public class TestStringBuilder { pu
我收到一份模型列表。模型的数量可能很大。这个模型有一堆属性,其中任何一个都可能是null。 我需要根据模型的属性为每个模型构建一个字符串。如果 property == null,那么我会在结果字符串中
我写了一些代码,其中有很多字符串创建。为了尽量避免一遍又一遍地创建昂贵的字符串,我使用了 java StringBuilder 类。 我的代码有点像这样: public String createSt
这个问题在这里已经有了答案: 关闭10年前。 Possible Duplicate: StringBuilder vs String concatenation in toString() in Ja
类 StringBuilder 定义了四个构造函数,它们都不接受 StringBuilder,但以下编译: StringBuilder sb = new StringBuilder(new Strin
我正在努力在我的代码中使用 StringBuilder,而不是 String使代码在所有解析和连接过程中具有时间效率。 但是当我查看它的源代码时,substring() 方法AbstractStrin
我想知道 StringBuilder,我有一个问题希望社区能够解释。 让我们忘掉代码的可读性,哪些是更快,为什么? StringBuilder.Append: StringBuilder sb = n
这个问题在这里已经有了答案: Single exclamation mark in Kotlin (6 个回答) Example of when should we use run, let, app
我已经附加了一些带有一些字符的 strBuild 并将该 strBuild 放入 stringBuildArr 中。然后在strBuild上调用java.lang.StringBuilder.dele
在 C# 中哪个内存效率更高:选项 #1 还是选项 #2? public void TestStringBuilder() { //potentially a collection with
当使用 StringBuilder.ToString() 时,我遇到了 OutOfMemory 异常。因为我的字符串需要很大的空间。这就是为什么我需要一种方法(也许通过流式传输)来让它工作。 这是我的
这个问题已经有答案了: What's the difference between instance method reference types in Java 8? (3 个回答) 已关闭 7 年
这个问题在这里已经有了答案: What's the difference between instance method reference types in Java 8? (3 个答案) 关闭
最近的 question came up关于使用 String.Format()。我的部分回答包括使用 StringBuilder.AppendLine(string.Format(...)) 的建议
在 SO 上看到一个关于连接字符串的问题后,我做了一些测试,了解到在 foreach 中连接字符串比使用 for 循环和使用数组中的索引慢。由于对数组进行绑定(bind)检查,for 循环不应该变慢吗
我的问题是如果我有时在同一个字符串上使用多线程 字符串不会被替换。(我在记事本上写了这个,所以语法可能是 错误) 使用 System.Thread ...当然还有其他 class .... {
如果我创建一个不可变类。所有字段都必须是最终的。如果我像这样使用 stringbuilder final StringBuilder s = new StringBuilder("你好"); ,那么
是否可以配置 Java StringBuilder类在每次调用之间追加一个新行以追加? 最佳答案 我不认为 StringBuilder内置了该功能。既然你不能只是扩展它,你可以尝试使用装饰器模式...
我是一名优秀的程序员,十分优秀!