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

Optimize the use of AtomicReferenceFieldUpdaters #8

Closed
wants to merge 7 commits into from
Closed

Optimize the use of AtomicReferenceFieldUpdaters #8

wants to merge 7 commits into from

Conversation

rovarga
Copy link
Contributor

@rovarga rovarga commented Sep 8, 2014

Benchmarks indicate that instatiating the updaters takes ~92% of the CPU
time required to initialize a TrieMap instance.

TrieMap.inodeupdater is an unused per-object updater, which has its
equivalent in INodeBase.updater.

rtupd is an unused istance, so we can freely remove it, lowering the
memory cost of a TrieMap just a tiny bit.

Finally, we centralize the allocation of rootupdater -- instead of
allocating it over and over again, we have a single instance which we
share.

Signed-off-by: Robert Varga nite@hq.sk

@romix
Copy link
Owner

romix commented Sep 9, 2014

Thanks for your PR. Could you report about performance when this changes is applied? How much better is it now?

@rovarga
Copy link
Contributor Author

rovarga commented Sep 10, 2014

No problem. It seem's Moiz's Serializable patch broke the tests (I am getting a StackOverflowError). I will investigate/patch and report back as soon as I can.


From: romix notifications@github.com
Sent: 09 September 2014 8:29 PM
To: romix/java-concurrent-hash-trie-map
Cc: Róbert Varga
Subject: Re: [java-concurrent-hash-trie-map] Optimize the use of AtomicReferenceFieldUpdaters (#8)

Thanks for your PR. Could you report about performance when this changes is applied? How much better is it now?

Reply to this email directly or view it on GitHubhttps://github.com//pull/8#issuecomment-55012934.
RóbertVarga
CTO

Mlynské Nivy 56 / 821 05 Bratislava / Slovakia
+421 910 309 248 / robert.varga@pantheon.sk
reception: +421 2 206 65 111 / www.pantheon.sk
[logo]

Robert Varga added 4 commits September 10, 2014 15:12
Internal constructor needs to pass down the arguments, so read-only
snapshots are created properly. This allows serialization to work as
expected. Also add serialVersionUID to fix some warnings.

Signed-off-by: Robert Varga <robert.varga@pantheon.sk>
Benchmarks indicate that instatiating the updaters takes ~92% of the CPU
time required to initialize a TrieMap instance.

TrieMap.inodeupdater is an unused per-object updater, which has its
equivalent in INodeBase.updater.

rtupd is an unused istance, so we can freely remove it, lowering the
memory cost of a TrieMap just a tiny bit.

Finally, we centralize the allocation of rootupdater -- instead of
allocating it over and over again, we have a single instance which we
share.

Signed-off-by: Robert Varga <nite@hq.sk>
Couple of improvements to the serialization strategy:
- emit the fact that the map is read-only, so we preserve that trait
- write out the size and entries ourselves, not via an intermediate
  HashMap()

The read path now takes these changes into account and resets the
rootupdater after deserialization is done back to null.

Signed-off-by: Robert Varga <robert.varga@pantheon.sk>
Removes duplicate fields and makes the equivalent methods final. Also
marks things that we take care of as transient, thus allowing us to
reuse the JVM magic in serialization.

Signed-off-by: Robert Varga <robert.varga@pantheon.sk>
@rovarga
Copy link
Contributor Author

rovarga commented Sep 10, 2014

Ugh, sorry for the slew of patches ... I can split them up into multiple merges (still learning here).

Robert Varga added 3 commits September 10, 2014 20:01
This reorganizes the initialization a bit and makes sure, that root node
is initialized even by the default constructor.

Signed-off-by: Robert Varga <robert.varga@pantheon.sk>
Instead of using the updater reference as the indicator of read-only
views, add an explicit boolean. Thus all instances reuse a single
updater reference, but still guard access to it via an explicit check.

This changes the behavior a bit: instead of throwing NPE on read-only
views, we throw IllegalStateException. The reason for that is that we
should have caught the attempt in the MAP API functions.

Signed-off-by: Robert Varga <robert.varga@pantheon.sk>
Adds explicit checks for read-only snapshot before attempting to perform
a modification operation. As per ConcurrentMap/Iterator interface
specification, throw an UnsupportedOperationException if such an attempt
is made.

Signed-off-by: Robert Varga <robert.varga@pantheon.sk>
@romix
Copy link
Owner

romix commented Sep 10, 2014

Yes. It would be nice if you split it into separate patches. The ones related to serialization and those related to atomics.

0.2.0 does 28583 initializations in 14098ms (0.493ms per instantiation)
0.2.1-SNAPSHOT with this patch does 1766 initializations in 48ms (0.027ms per instantiation)

Why is it tested with different number of initializations? Couldn't it be done for the same number just for the sake of comparing apples to apples?

@rovarga
Copy link
Contributor Author

rovarga commented Sep 15, 2014

Closing this one, will reopen a few point PRs.

@rovarga rovarga closed this Sep 15, 2014
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.

None yet

2 participants