-
Notifications
You must be signed in to change notification settings - Fork 361
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Re-implement PrintStream.print(obj: AnyRef)
to avoid a CharSequence -> String conversion
#2933
base: main
Are you sure you want to change the base?
Conversation
….toString call (unit test added)
First, thank you for the contribution. I am at the end of a long sprint right now so I can not do the obvious and try it out.
I suspect that the Since a String is a kind of CharSequence, what happens if the Am I being silly or missing something? Does it have any utility or benefit? The rest of the code looks good to me. It is still simmering in CI as I |
Sharp eyes. I have the feeling it's a bit inconsistent. Disturbing, isn't it? Now to reply precisely to your question:
Tested in Scastie with: class Printer {
//def printThis(s: String): Unit = println(if (s == null) "null" else s)
def printThis(obj: AnyRef): Unit = {
obj match {
case csq: java.lang.CharSequence => println("csq")
case _ => { println("bar") ; println(String.valueOf(obj)) }
}
}
}
var csq: CharSequence = new StringBuilder("test")
csq = null
new Printer().printThis(csq) |
So the I think I am missing something about the main idea of this PR: increase performance by reducing allocations. By my tracing of encoder.append() -> OutputStreamWriter.append. OSW inherits it append from Writer, which has
Sorry, I am missing where a "CharSequence -> String" conversion is being avoided in the I am supportive of the idea & goal. For those following along: Still, avoiding even a 16 byte allocation is worth it if it can be done within economic bounds.The current path for a CharSequence, say StringBuilder, goes through
Both do a The append() of the current PR ends up a the same underlying
|
If we could come up with an Java 8 CharSequence has no public I suspect that over time, as CharSequence work is done, there will be a general need for I am off to remind myself how
Later: I find no
I think this, plus the current PR, would save one String (and interior Array[Char]) allocation & copy of chars |
It looks like I was over confident in the ability of I'll commit quickly an updated version. |
| I'll commit quickly an updated version. I think this is not a sprint and not a marathon but rather than an ultra-marathon. My suggestion is to take your time & enjoy the puzzle. Thank you for confirming my tracing. I always wonder if I am seeing what I think I am seeing. |
…her allocations Unit test updated to be sure we don't introduce regressions.
I hope this will make it.
I don't like some lines there though: |
David, I have not lost interest. It is going to take me a few days to review your latest proposal. Some thoughts from over the weekend, against the background
We may have to explore several paths and that can be frustrating. I for one, |
Absolutely not an issue, as I'm also very busy this week.
Thank you again for your input. I have no issue with a different approach.
I don't get the suggestion about
We could eventually use the existing method The alternative, which is aligned with your proposal, would be to use the existing method It's true that it would avoid to create a String wrapper, but won't be a zero-copy operation. So we still generate additional garbage that could increase GC pressure (for heavy workloads). What I like with the
For now, the best solution I came up with, consists in wrapping the CharSequence in a CharBuffer using
The main reason of this wrapping, is that While I would prefer to have an
Let's hope we will find on a solution which is both simple, robust and efficient. |
Hi @LeeTibbert. |
@david-bouyssie Will do. It will have to be tomorrow, Weds. A lot of discussion has been happening in the String allocation area and I need to |
Well, it should. I'm just worried that it is not... |
This PR is WIP to fix #2906
This issue is focusing on the PrintStream use case, but there are maybe other places in the code where using
CharSequence
instead ofString
could be beneficial.This PR reimplements the method
PrintStream.print(obj: AnyRef)
in order to callencoder.append(csq)
instead ofencoder.write(s)
, encoder being anOutputStreamWriter
.This allows to avoid the current conversion of
CharSequence
toString
, and should thus save both CPU and memory consumption.This PR is a nice workaround to PR #2908, which is proposing a reimplementation of
AbstractStringBuilder.toString
,AbstractStringBuilder
being one possibleCharSequence
of javalib. But it only works for StringBuilder/StringBuffer used in this context. The PR #2908 tries to solve the allocation issue in more generic way (through a carefully tuned sharing strategy).The present PR has however the advantage of fewer consequences in terms of logic (no side effect).