-
Notifications
You must be signed in to change notification settings - Fork 596
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
optimize zip() by pre-sizing target. Fixes #376 #435
Conversation
Thanks @nolequen for the PR. From the contract of zip(), we need to pre-size the target collection to the minimum size of the two iterables. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please pre-size the target collection to the minimum size of the two iterables.
@nikhilnanivadekar, thanks for the feedback! Can you please take a look at the current version. |
@nolequen can you please rebase on to master that will have @donraab 's changes merged on your branch and squash the commits. We like to keep the git log history incremental otherwise it becomes difficult to trace the changes in git log. Also regarding pre-sizing it using Iterate.sizeOf() I think we would need to do an instance check since Iterate.sizeOf() is O(n) for Iterable which is not a Collection or RichIterable. See here: L3183 |
@@ -852,7 +852,9 @@ final class Immutable<name>ObjectSingletonMap\<V> extends AbstractImmutable<name | |||
@Override | |||
public \<S> ImmutableBag\<Pair\<V, S>\> zip(Iterable\<S> that) | |||
{ | |||
return this.zip(that, HashBag.\<Pair\<V, S>\>newBag()).toImmutable(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is ok to not pre-size in this file. Since the max the zipped Bag will be is of size 1. Pre-sizing it to 1 defaults it to 10.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I see in objectPrimitiveHashMap.stg pre-sizing to 1 gives map capacity=2 while without presizing it gives capacity=16.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nikhilnanivadekar what kind of instance check do you mean? can you provide an example?
Also 1 more request, can you please update the copyright to be 2018 and also add and others. |
ecc0d9d
to
8202137
Compare
@@ -1,4 +1,4 @@ | |||
import "copyright.stg" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please revert this file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
} | ||
|
||
@Override | ||
public MutableSet<V> select(Predicate<? super V> predicate) | ||
{ | ||
return this.delegate.select(predicate, new UnifiedSet<>()); | ||
return this.delegate.select(predicate, UnifiedSet.newSet(this.size())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We cannot pre-size for select() as we do not know beforehand for how many elements the Predicate will return true. Can you please revert this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for this. Reverted.
@@ -1465,7 +1465,9 @@ public class <name>ObjectHashMap\<V> implements Mutable<name>ObjectMap\<V>, Exte | |||
@Override | |||
public \<S> MutableBag\<Pair\<V, S>\> zip(Iterable\<S> that) | |||
{ | |||
return this.zip(that, HashBag.\<Pair\<V, S>\>newBag()); | |||
int thatSize = Iterate.sizeOf(that); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if(that instanceof Collection || that instanceOf RichIterable)
{
int thatSize = Iterate.sizeOf(that)
HashBag\<Pair\<V, S>\> target = HashBag.newBag(Math.min(this.size(), thatSize));
return this.zip(that, target)
}
return this.zip(that, HashBag.\<Pair\<V, S>\>newBag());
I meant by instance check for only Collection or RichIterable as shown below:
|
d36b111
to
e5ceeab
Compare
Signed-off-by: nolequen <nolequen@gmail.com>
Thanks for your contribution! |
Sorry I'm late to this. I just came across this while working on something else. I think this is a deoptimization and we should either fix it or revert it. For context, here's an example implementation today: @Override
public <S> MutableList<Pair<T, S>> zip(Iterable<S> that)
{
if (that instanceof Collection || that instanceof RichIterable)
{
int thatSize = Iterate.sizeOf(that);
FastList<Pair<T, S>> target = FastList.newList(Math.min(this.size(), thatSize));
return this.zip(that, target);
}
return this.zip(that, FastList.newList());
} The problem is the clause public interface LazyIterable<T>
extends RichIterable<T> If |
Here are two somewhat contrived examples that terminate instantly with 9.1.0 and need to be Ctrl+C killed with the current version. @Test
public void concatenate()
{
MutableList<Integer> smallList = Lists.mutable.with(1, 2, 3);
Interval bigInterval = Interval.zeroTo(Integer.MAX_VALUE);
LazyIterable<Integer> lazyEmptyInterval = bigInterval.select(x -> false);
LazyIterable<Integer> concatenate = smallList.asLazy().concatenate(lazyEmptyInterval);
MutableList<Pair<Integer, Integer>> zipped = smallList.zip(concatenate);
assertEquals(smallList.zip(smallList), zipped);
}
@Test
public void empty()
{
MutableList<Integer> emptyList = Lists.mutable.empty();
Interval bigInterval = Interval.zeroTo(Integer.MAX_VALUE);
LazyIterable<Integer> lazyEmptyInterval = bigInterval.select(x -> false);
MutableList<Pair<Integer, Integer>> zipped = emptyList.zip(lazyEmptyInterval);
assertEquals(Lists.mutable.empty(), zipped);
} |
Hope, I found all of them.