Skip to content
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

Fixes SI-5387: Improve Performance Of dropWhile in TraversableLike #113

Closed
wants to merge 1 commit into from

Conversation

cvogt
Copy link
Contributor

@cvogt cvogt commented Jan 19, 2012

The predicate was evaluated repeatedly for every element, even every non-dropped one.

…-evaluating the predicate after it once evaluated to true.

Closes SI-5387.
@paulp
Copy link
Contributor

paulp commented Jan 19, 2012

Can you add a test case?

@cvogt cvogt closed this Jan 19, 2012
eed3si9n pushed a commit to eed3si9n/scala that referenced this pull request May 14, 2019
`SafeLazy` has been traditionally implemented in `zincApiInfo` because
it is part of the sbt API and is accessible to all the subprojects that
depend on it.

Before this commit, `SafeLazy` was a runtime dependency (using
reflection) of the compiler bridge. In this regard, Zinc was assuming
that the sbt API was accessible at runtime and therefore invoked it to
use an implementation of lazy that would remove references to the thunks
once they've been forced. This was done to free memory as soon as
possible since those thunks usually depend on classes of compiler
internals and would not be GC'ed otherwise.

However, the compiler bridge is not supposed to depend on sbt APIs since
its code is compiled by the Scala compiler that the user picks in SBT.
Its only dependency is the compiler interface, which is implemented in
Java and compiled beforehand with javac.

This commit removes the runtime dependency of the compiler bridge to the
sbt API and avoids the method invocations using reflection. This was
done for the following reasons:

* Simplicity. It is not obvious why `SafeLazy` is invoked reflectively.
  See sbt/zinc#113.
* Performance. Even though the JVM should make this simple use of
  reflection fast, there's a very small overhead of using reflection in
  the compiler bridge because `lzy` is (most likely) hot.

The fix consists of a Java implementation of `SafeLazy` that uses the
non-thread-safe lazy val implementation described [here](http://docs.scala-lang.org/sips/pending/improved-lazy-val-initialization.html).
It is complemented with a proxy written in Scala that will create an
indirection layer for things like by-name and strict evaluation.
This implementation of lazy val assumes that `SafeLazy` will never be
called asynchronously. If this is the case, it's up to the Zinc
maintainer to make sure that safe publishing is implemented at the
call-site or to change the implementation to avoid races and
uninitialized fields.
lrytz pushed a commit to lrytz/scala that referenced this pull request Nov 5, 2019
`SafeLazy` has been traditionally implemented in `zincApiInfo` because
it is part of the sbt API and is accessible to all the subprojects that
depend on it.

Before this commit, `SafeLazy` was a runtime dependency (using
reflection) of the compiler bridge. In this regard, Zinc was assuming
that the sbt API was accessible at runtime and therefore invoked it to
use an implementation of lazy that would remove references to the thunks
once they've been forced. This was done to free memory as soon as
possible since those thunks usually depend on classes of compiler
internals and would not be GC'ed otherwise.

However, the compiler bridge is not supposed to depend on sbt APIs since
its code is compiled by the Scala compiler that the user picks in SBT.
Its only dependency is the compiler interface, which is implemented in
Java and compiled beforehand with javac.

This commit removes the runtime dependency of the compiler bridge to the
sbt API and avoids the method invocations using reflection. This was
done for the following reasons:

* Simplicity. It is not obvious why `SafeLazy` is invoked reflectively.
  See sbt/zinc#113.
* Performance. Even though the JVM should make this simple use of
  reflection fast, there's a very small overhead of using reflection in
  the compiler bridge because `lzy` is (most likely) hot.

The fix consists of a Java implementation of `SafeLazy` that uses the
non-thread-safe lazy val implementation described [here](http://docs.scala-lang.org/sips/pending/improved-lazy-val-initialization.html).
It is complemented with a proxy written in Scala that will create an
indirection layer for things like by-name and strict evaluation.
This implementation of lazy val assumes that `SafeLazy` will never be
called asynchronously. If this is the case, it's up to the Zinc
maintainer to make sure that safe publishing is implemented at the
call-site or to change the implementation to avoid races and
uninitialized fields.

Rewritten from sbt/zinc@c1f821b
retronym referenced this pull request in retronym/scala Mar 24, 2020
[backport] Avoid masking real errors with NotImplemented awaiting Future[Nothing]
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.

2 participants