Giter Site home page Giter Site logo

Comments (9)

jansupol avatar jansupol commented on July 23, 2024 1

I have copied the ByteArrayOutputStream into a new file and replaced the synchronized with the ReentrantLock. The synchronized blocks are 10x faster.

from jersey.

jansupol avatar jansupol commented on July 23, 2024

At first glance, adaptedOutput.write(buffer.toByteArray()); seems worse performance-wise as it is synchronized too and it creates a copy of the data buffer for each call. We should measure the performance and have the change for JDK 21+ only, if worse on JDK [8,20)

from jersey.

vasanth-bhat avatar vasanth-bhat commented on July 23, 2024

At first glance, adaptedOutput.write(buffer.toByteArray()); seems worse performance-wise as it is synchronized too

Yes, BufferedOutputStream.toByteArray() is synchronised , but it does not lead to the specific issue of carrier thread pinning, as there is no IO happening from with this sync block.

https://github.com/openjdk/jdk/blob/jdk-21%2B35/src/java.base/share/classes/java/io/ByteArrayOutputStream.java

public synchronized byte[] toByteArray() {
return Arrays.copyOf(buf, count);
}

yes, It does make Array copy .

Looking further at the. stack snippet. in this scenario, the concrete type of "adaptedOutput" is of. type. "TracingObserver$TracingStreamOutputDelegate" .

https://github.com/helidon-io/helidon/blob/e93ee0c0c9b8762212a7f07cb473fec6bc52d827/webserver/observe/tracing/src/main/java/io/helidon/webserver/observe/tracing/TracingObserver.java#L490

Further, The BufferedOutputStream.write() is synchronized only when it is subclassed and not used directly.
https://github.com/openjdk/jdk/blob/890adb6410dab4606a4f26a942aed02fb2f55387/src/java.base/share/classes/java/io/BufferedOutputStream.java#L87

Stack Snippet

io.helidon.webserver.http1.Http1ServerResponse$BlockingOutputStream.write(Http1ServerResponse.java:585) io.helidon.webserver.http1.Http1ServerResponse$BlockingOutputStream.write(Http1ServerResponse.java:470) java.base/[java.io](http://java.io/).BufferedOutputStream.implWrite(BufferedOutputStream.java:217) java.base/[java.io](http://java.io/).BufferedOutputStream.write(BufferedOutputStream.java:200) io.helidon.webserver.http1.Http1ServerResponse$ClosingBufferedOutputStream.write(Http1ServerResponse.java:749) io.helidon.webserver.observe.tracing.TracingObserver$TracingStreamOutputDelegate.write(TracingObserver.java:525) java.base/[java.io](http://java.io/).ByteArrayOutputStream.writeTo(ByteArrayOutputStream.java:163) <== monitors:1 org.glassfish.jersey.message.internal.CommittingOutputStream.flushBuffer(CommittingOutputStream.java:278) org.glassfish.jersey.message.internal.CommittingOutputStream.commit(CommittingOutputStream.java:232)

from jersey.

jansupol avatar jansupol commented on July 23, 2024

Interesting test results, for buffer=ByteArrayOutputStream, adaptedOutput=FileOutputStream, 32MB written:

|    JDK     |     Actual  Method    |      Proposed Method      |
| -------------------------------------------------------------- |  
|     8      |        90ms           |              98ms         |
|     11     |        35ms           |              40ms         | 
|     17     |        45ms           |              50ms         |
|     21     |        43ms           |              48ms         | 

It looks like the proposed method is about 10% slowlier, no virtual threads. So we should have this just for virtual threads.

from jersey.

jansupol avatar jansupol commented on July 23, 2024

Perhaps a better solution is to have a ByteArrayOutputStream without synchronized blocks, with reentrant locks instead to avoid data copying.

from jersey.

jansupol avatar jansupol commented on July 23, 2024

#5629 Is for 2.x and 3.0, we should check for Thread#isVirtual in 3.1 and forward.

from jersey.

jansupol avatar jansupol commented on July 23, 2024

Keep open for 3.1

from jersey.

vasanth-bhat avatar vasanth-bhat commented on July 23, 2024

#5632 fixes the issue in 2.4.3.

Helidon 4.x. uses jersey 3.1.5
https://github.com/helidon-io/helidon/blob/main/dependencies/pom.xml
<version.lib.jersey>3.1.5</version.lib.jersey>

Which version of 3.1 would have this fix for Helidon to uptake?

from jersey.

jansupol avatar jansupol commented on July 23, 2024

The next one, 3.1.7

from jersey.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.