8000 Improve memory usage in Ref.Atomic by maximskripnik · Pull Request #9710 · zio/zio · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Improve memory usage in Ref.Atomic #9710

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

Merged
merged 2 commits into from
Mar 18, 2025

Conversation

maximskripnik
Copy link
Contributor

Fixes #9709

@CLAassistant
Copy link
CLAassistant commented Mar 18, 2025

CLA assistant check
All committers have signed the CLA.

@maximskripnik maximskripnik force-pushed the fix-ref-initial branch 2 times, most recently from 134b828 to 007fded Compare March 18, 2025 10:45
@maximskripnik
Copy link
Contributor Author
maximskripnik commented Mar 18, 2025

Not sure which behaviour for toString is preferred:

  1. The current behaviour (so before the fix), where the initial value is printed. This can be implemented like this (see my comment in Suboptimal memory usage for zio.Atomic (inside zio.Ref) #9709):
private[zio] final class Atomic[A](initial: A) extends Ref[A] { self =>
  private val initialStr = initial.toString
  ...
  override def toString: String = s"Ref.Atomic(initial = $initialStr)"
  ...
}

While this could be useful in some scenarios, depending on toString implementation in A, it could still consume quite a bit of memory. So I am not sure it's a good idea still

  1. The old behaviour prior to 2.1.15, where the current value is printed. Since toString can not be suspended, the only way to do it is by accessing unsafe:
override def toString: String = s"Ref.Atomic(${unsafe.get(Unsafe)})"

This fixes the issue and is arguably a more useful toString implementation, cause you probably care more about the current value inside ref rather then the initial value. However, it was argued by @hearnadam to be unnecessary in #9500. I agree with what he says, but I can't tell if that's better than other options

  1. Not print any content of the wrapped value at all, that's the current version in this PR:
override def toString: String = s"Ref.Atomic"

Needless to say, this is the least useful version, but at least it certainly doesn't bring any problems with memory or calling unsafe code outside of zio

Please let me know what option you prefer, or maybe there is a better way to fix it that I can't see 👀
Thanks a lot!

@hearnadam
Copy link
Collaborator

Thanks for the contribution, and fixing my mistake. I think either behavior is fine (with a bias to no value shown) - perhaps @kyri-petrou or @ghostdogpr have an opinion on the behavior.

@@ -359,7 +359,7 @@ object Ref extends Serializable {
override def updateSomeAndGet(pf: PartialFunction[A, A])(implicit trace: Trace): UIO[A] =
ZIO.succeed(unsafe.updateSomeAndGet(pf)(Unsafe))

override def toString: String = s"Ref.Atomic(initial = $initial)"
override def toString: String = s"Ref.Atomic"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What value is printed if we don't override?

Copy link
Contributor Author
@maximskripnik maximskripnik Mar 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just the default java implementation that prints hash, so like zio.Ref$Atomic@2d97c38c. This actually seems better than what I put now 😅 So let's not override (and remove the test)? To be fair, the more I think about it, the less sense it makes to override toString here in the first place. Like if you want to see the current value (as it was prior your fix), just do .get and do .toString on that, this way you suspend everything that needs to be suspended. Expecting Ref#toString to print some content of the wrapped value is odd

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I agree. We can just remove the override + test.

@hearnadam hearnadam merged commit 36f97ba into zio:series/2.x Mar 18, 2025
18 checks passed
@maximskripnik maximskripnik deleted the fix-ref-initial branch March 19, 2025 06:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Suboptimal memory usage for zio.Atomic (inside zio.Ref)
3 participants
0