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

CAMEL-19295: Basic thread-safe LRU cache #10157

Merged
merged 2 commits into from
May 24, 2023
Merged

CAMEL-19295: Basic thread-safe LRU cache #10157

merged 2 commits into from
May 24, 2023

Conversation

davsclaus
Copy link
Contributor

…se will OOME

Description

Target

  • I checked that the commit is targeting the correct branch (note that Camel 3 uses camel-3.x, whereas Camel 4 uses the main branch)

Tracking

  • If this is a large change, bug fix, or code improvement, I checked there is a JIRA issue filed for the change (usually before you start working on it).

Apache Camel coding standards and style

  • I checked that each commit in the pull request has a meaningful subject line and body.
  • I formatted the code using mvn -Pformat,fastinstall install && mvn -Psourcecheck

@github-actions
Copy link
Contributor

🌟 Thank you for your contribution to the Apache Camel project! 🌟

🐫 Maintainers, please note that first-time contributors require manual approval for the GitHub Actions to run.

⚠️ Please note that the changes on this PR may be tested automatically if they change components.

If necessary Apache Camel Committers may access logs and test results in the job summaries!

@github-actions
Copy link
Contributor

🚫 There are (likely) no components to be tested in this PR

@orpiske
Copy link
Contributor

orpiske commented May 23, 2023

@davsclaus I've just got the results of testing this code. It has quite a big impact in concurrent scenarios. I run some tests comparing with Camel 4.0.0-M3 (baseline) with this patch.

For resolving the endpoints:

Baseline:

Benchmark                                Mode  Cnt  Score   Error  Units
EndpointResolveTest.testActionStatus_1   avgt   10  3.273 ± 0.003  us/op
EndpointResolveTest.testActionStatus_16  avgt   10  3.674 ± 0.007  us/op
EndpointResolveTest.testActionStatus_2   avgt   10  3.314 ± 0.002  us/op
EndpointResolveTest.testActionStatus_32  avgt   10  4.738 ± 0.020  us/op
EndpointResolveTest.testActionStatus_4   avgt   10  3.730 ± 0.001  us/op
EndpointResolveTest.testActionStatus_8   avgt   10  3.400 ± 0.002  us/op

This patch:

Benchmark                                Mode  Cnt   Score   Error  Units
EndpointResolveTest.testActionStatus_1   avgt   10   3.727 ± 0.002  us/op
EndpointResolveTest.testActionStatus_16  avgt   10  12.688 ± 1.002  us/op
EndpointResolveTest.testActionStatus_2   avgt   10   3.405 ± 0.003  us/op
EndpointResolveTest.testActionStatus_32  avgt   10  25.113 ± 0.785  us/op
EndpointResolveTest.testActionStatus_4   avgt   10   3.792 ± 0.001  us/op
EndpointResolveTest.testActionStatus_8   avgt   10   3.741 ± 0.014  us/op

Note: the _X is the number of threads (i.e.; EndpointResolveTest.testActionStatus_4 is the test with 4 threads).

For the endpoint registry operations:

Baseline:

Benchmark                                          Mode  Cnt     Score    Error  Units
EndpointRegistryTest.testContainsExistentKey       avgt   10    17.696 ±  0.007  us/op
EndpointRegistryTest.testContainsNonExistentKey    avgt   10     5.190 ±  0.001  us/op
EndpointRegistryTest.testContainsNonExistentValue  avgt   10  1866.783 ±  0.401  us/op
EndpointRegistryTest.testDynamicSize               avgt   10     0.002 ±  0.001  us/op
EndpointRegistryTest.testIsDynamic                 avgt   10  1045.090 ±  1.387  us/op
EndpointRegistryTest.testReadOnlyMap               avgt   10    18.633 ±  0.017  us/op
EndpointRegistryTest.testReadOnlyValues            avgt   10     5.812 ±  0.025  us/op

This patch:

Benchmark                                          Mode  Cnt     Score    Error  Units
EndpointRegistryTest.testContainsExistentKey       avgt   10    23.900 ±  0.006  us/op
EndpointRegistryTest.testContainsNonExistentKey    avgt   10    21.621 ±  0.032  us/op
EndpointRegistryTest.testContainsNonExistentValue  avgt   10  1866.985 ±  0.566  us/op
EndpointRegistryTest.testDynamicSize               avgt   10     0.027 ±  0.001  us/op
EndpointRegistryTest.testIsDynamic                 avgt   10  1003.702 ± 61.613  us/op
EndpointRegistryTest.testReadOnlyMap               avgt   10    19.331 ±  0.009  us/op
EndpointRegistryTest.testReadOnlyValues            avgt   10     5.895 ±  0.024  us/op

And the impact is quite extreme for the registry under concurrent access:

Baseline:

Benchmark                                                       Mode  Cnt     Score    Error  Units
EndpointRegistryScalabilityTest.testContainsNonExistentKey_2    avgt   10    17.520 ±  0.010  us/op
EndpointRegistryScalabilityTest.testContainsNonExistentKey_4    avgt   10    16.919 ±  0.002  us/op
EndpointRegistryScalabilityTest.testContainsNonExistentKey_8    avgt   10    16.848 ±  0.009  us/op
EndpointRegistryScalabilityTest.testContainsNonExistentValue_2  avgt   10  1881.827 ±  0.240  us/op
EndpointRegistryScalabilityTest.testContainsNonExistentValue_4  avgt   10  1873.975 ±  0.102  us/op
EndpointRegistryScalabilityTest.testContainsNonExistentValue_8  avgt   10  1904.569 ±  0.129  us/op
EndpointRegistryScalabilityTest.testDynamicSize_2               avgt   10     0.002 ±  0.001  us/op
EndpointRegistryScalabilityTest.testDynamicSize_4               avgt   10     0.002 ±  0.001  us/op
EndpointRegistryScalabilityTest.testDynamicSize_8               avgt   10     0.002 ±  0.001  us/op
EndpointRegistryScalabilityTest.testIsDynamic_2                 avgt   10  1005.876 ±  0.376  us/op
EndpointRegistryScalabilityTest.testIsDynamic_4                 avgt   10   984.097 ±  0.402  us/op
EndpointRegistryScalabilityTest.testIsDynamic_8                 avgt   10  1000.953 ±  0.392  us/op
EndpointRegistryScalabilityTest.testReadOnlyMap_2               avgt   10    20.184 ±  0.020  us/op
EndpointRegistryScalabilityTest.testReadOnlyMap_4               avgt   10    19.486 ±  0.010  us/op
EndpointRegistryScalabilityTest.testReadOnlyMap_8               avgt   10    19.062 ±  0.028  us/op
EndpointRegistryScalabilityTest.testReadOnlyValues_2            avgt   10     6.539 ±  0.012  us/op
EndpointRegistryScalabilityTest.testReadOnlyValues_4            avgt   10     6.498 ±  0.004  us/op
EndpointRegistryScalabilityTest.testReadOnlyValues_8            avgt   10     6.782 ±  0.018  us/op

This patch:

Benchmark                                                       Mode  Cnt      Score     Error  Units
EndpointRegistryScalabilityTest.testContainsNonExistentKey_2    avgt   10    138.018 ±   5.506  us/op
EndpointRegistryScalabilityTest.testContainsNonExistentKey_4    avgt   10    347.650 ±   4.114  us/op
EndpointRegistryScalabilityTest.testContainsNonExistentKey_8    avgt   10   2727.941 ±  27.952  us/op
EndpointRegistryScalabilityTest.testContainsNonExistentValue_2  avgt   10   4908.715 ± 434.815  us/op
EndpointRegistryScalabilityTest.testContainsNonExistentValue_4  avgt   10   9054.876 ±  61.169  us/op
EndpointRegistryScalabilityTest.testContainsNonExistentValue_8  avgt   10  18575.008 ± 321.350  us/op
EndpointRegistryScalabilityTest.testDynamicSize_2               avgt   10      0.121 ±   0.001  us/op
EndpointRegistryScalabilityTest.testDynamicSize_4               avgt   10      0.576 ±   0.002  us/op
EndpointRegistryScalabilityTest.testDynamicSize_8               avgt   10      1.915 ±   0.008  us/op
EndpointRegistryScalabilityTest.testIsDynamic_2                 avgt   10   1050.203 ±   2.756  us/op
EndpointRegistryScalabilityTest.testIsDynamic_4                 avgt   10   1093.550 ±  60.650  us/op
EndpointRegistryScalabilityTest.testIsDynamic_8                 avgt   10   3698.012 ±  16.992  us/op
EndpointRegistryScalabilityTest.testReadOnlyMap_2               avgt   10     20.164 ±   0.038  us/op
EndpointRegistryScalabilityTest.testReadOnlyMap_4               avgt   10     19.920 ±   0.008  us/op
EndpointRegistryScalabilityTest.testReadOnlyMap_8               avgt   10     19.935 ±   0.025  us/op
EndpointRegistryScalabilityTest.testReadOnlyValues_2            avgt   10      6.683 ±   0.028  us/op
EndpointRegistryScalabilityTest.testReadOnlyValues_4            avgt   10      6.528 ±   0.013  us/op
EndpointRegistryScalabilityTest.testReadOnlyValues_8            avgt   10      7.064 ±   0.026  us/op

@davsclaus
Copy link
Contributor Author

Yeah can you test with camel-caffeine-lrucache as well.

Also I think we can have a non LRU cache, we often just want to keep 1000 elements in a cache, and they may not need to be exact LRU based. So they can be FIFO or anything like that, just that the size of big enough for normal use-cases.

So basically we can make a cache that is just a ConcurrentMap from the JDK to be used in the various places, where a LRU is really not needed.

@orpiske
Copy link
Contributor

orpiske commented May 23, 2023

Sure thing. Let me run the tests with camel-caffeine-lrucache and see how it goes. I believe we can have the results today still.

Also I think we can have a non LRU cache, we often just want to keep 1000 elements in a cache, and they may not need to be exact LRU based. So they can be FIFO or anything like that, just that the size of big enough for normal use-cases.

Indeed. Maybe, it's the case we could go with a simpler alternative by default and ... if needed, we can leave it flexible so users can plug a more extensible one if they need to.

I was thinking maybe, we could have a ring buffer (circular queue). IMHO, we may not necessarily need to expire the least-recently used records, but we could overwrite them if needed be.

@essobedo
Copy link
Contributor

@davsclaus if it helps I have an idea of how to implement a basic thread-safe LRU cache. Let me know if you are interested.

@davsclaus
Copy link
Contributor Author

davsclaus commented May 23, 2023

@essobedo yeah sure, we may only need LRU in some situations

  • dynamic endpoint registry (LRU could be avoided and just have a reasonable big size)
  • simple cache (LRU not needed, cache size can be reasonable)
  • jmx mbean cache (LRU not needed, only in use during startup) - we can have a bigger size, and clear the cache after startup
  • service pool (only for non singleton = only a few components: ftp, ssh, mina, avro-rpc) and as this is only 4 components then LRU is not needed
  • bean introspection (LRU likely not as needed if we have a big enough size - LRU has overhead to reorder on get)
  • file idempotent repository (is LRU based today - can be synchronized as it does not need super fast (read/write to disk anyway)
  • MemoryIdempotentRepository can be synchronized as it does not need super fast (memory only for development)

@orpiske
Copy link
Contributor

orpiske commented May 23, 2023

@essobedo if you come up with the LRU Cache relatively soon - no pressure - I also offer to run the same tests on the perf lab I have access. I should have access to the machines for a few more weeks, so it should be fine.

@davsclaus
Copy link
Contributor Author

@essobedo you are welcome to provide a LRUCache then @orpiske can give it a test in his lab.
After that we can look whether we can refine and avoid LRU where its not really needed anyway - a ConcurrentMap from JDK is the fastest.

@essobedo
Copy link
Contributor

Ok I try to provide something today

@essobedo
Copy link
Contributor

@davsclaus May I use the same branch? Or should I create another one?

@davsclaus
Copy link
Contributor Author

yes sure you are welcome to use this branch or whatever you think is best

@rhuan080
Copy link
Contributor

rhuan080 commented May 23, 2023

Hi, I have created the CAMEL-19311 to discuss the LRU. I'm adding the issue here just to link this issue to the JIRA issue opened by me.

@@ -53,7 +54,7 @@ public <K, V> Map<K, V> createLRUCache(int maximumCacheSize) {
@Override
public <K, V> Map<K, V> createLRUCache(int maximumCacheSize, Consumer<V> onEvict) {
LOG.trace("Creating LRUCache with maximumCacheSize: {}", maximumCacheSize);
return new SimpleLRUCache<>(16, maximumCacheSize, onEvict);
return Collections.synchronizedMap(new SimpleLRUCache<>(16, maximumCacheSize, onEvict));
Copy link
Contributor

@rhuan080 rhuan080 May 23, 2023

Choose a reason for hiding this comment

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

I think it can impact code casting to SimpleLRUCache to use some SimpleLRUCache's methods.

protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {

@essobedo
Copy link
Contributor

@orpiske could you please try this?

@github-actions
Copy link
Contributor

🚫 There are (likely) no components to be tested in this PR

@ben-manes
Copy link

ben-manes commented May 24, 2023

Second Chance (Clock) is very easy to implement to give LRU like hit rates, high read concurrency, and is a good fit for small custom caches. It is basically a FIFO with a mark bit that is set on read. On a write a global lock is acquired, the FIFO is scanned resetting the mark bit, and the first unset entry is chosen for eviction. This means the worst case is O(n), which is fine for a cache of a few thousand entries. As reads are the common case, writes that block on this lock to perform a small amount of work is acceptable.

When brainstorming approaches for ConcurrentLinkedHashMap (Guava/Caffeine predecessor), that was my original approach that triggered my interest when solving some work performance problems. I had to release that as a pre-1.0 beta to mitigate people from using my unstable concurrent lru alpha code, so you can see review that as a reference and a basic analysis.

@davsclaus
Copy link
Contributor Author

Thanks @ben-manes for sharing your knowledge to the Camel community.

The code for the Caffeine LRU Cache is here
https://github.com/apache/camel/tree/camel-3.x/components/camel-caffeine-lrucache/src/main/java/org/apache/camel/component/caffeine/lrucache

It may be that we can improve this and our situation with Camel is the cache sizes are small (1000) (never huge)

And today maybe the warmup is not as needed (we run a lot of unit tests and start/stop Camel frequently, so fast startup in these test is preferred)
https://github.com/apache/camel/blob/camel-3.x/components/camel-caffeine-lrucache/src/main/java/org/apache/camel/component/caffeine/lrucache/CaffeineLRUCacheFactory.java#L53

@ben-manes
Copy link

Oh that’s great. I simply meant that if you want to make this existing lru cache concurrent without a dependency, then second chance is an effective approach that should be easy to maintain. Your pr changes also look reasonable.

@ben-manes
Copy link

For warmup, a very long time ago the builder had a class loading issue because it selected the implementation by a string switch. That seemed to cause the factory to be slow to classload due to the constant pool. I don’t think it would have tried to load the implementations, but it was oddly visible. The cache uses codegen variants to minimize the memory footprint, e.g. have ttl entry fields only if expirable.

That was fixed by using reflection which also trimmed the jar bloat. The current version can instantiate 180k/s. This has done in 2.6.1 (2017).

An unreleased optimization cached that reflective load so it becomes a direct call on subsequent usages. That resulted in 4M/s. Happy to release it if the current time is still an issue and the snapshot jar shows an improvement.

@orpiske
Copy link
Contributor

orpiske commented May 24, 2023

@orpiske could you please try this?

I'll try this one today. I think I can post the results by COB.

@oscerd
Copy link
Contributor

oscerd commented May 24, 2023

Thanks a lot @ben-manes for sharing your knowledge.

@essobedo essobedo force-pushed the lru-sync branch 2 times, most recently from 1b04d05 to 34184b5 Compare May 24, 2023 08:17
@essobedo
Copy link
Contributor

essobedo commented May 24, 2023

@orpiske FYI, I've changed a bit the implementation for something easier to maintain and closer in terms of behavior to the initial non thread-safe implementation

@orpiske
Copy link
Contributor

orpiske commented May 24, 2023

@orpiske FYI, I've changed a bit the implementation for something easier to maintain and closer in terms of behavior to the initial non thread-safe implementation

Thanks for the heads up. That's OK, the test should start in about 1 hour or so, so it should pick the updated one.

@essobedo essobedo force-pushed the lru-sync branch 3 times, most recently from 83d9295 to 1c0a8e9 Compare May 24, 2023 08:42
@github-actions
Copy link
Contributor

↩️ There are either too many changes to be tested in this PR or the code needs be rebased: (271 components likely to be affected)

1 similar comment
@github-actions
Copy link
Contributor

↩️ There are either too many changes to be tested in this PR or the code needs be rebased: (271 components likely to be affected)

@github-actions
Copy link
Contributor

↩️ There are either too many changes to be tested in this PR or the code needs be rebased: (271 components likely to be affected)

4 similar comments
@github-actions
Copy link
Contributor

↩️ There are either too many changes to be tested in this PR or the code needs be rebased: (271 components likely to be affected)

@github-actions
Copy link
Contributor

↩️ There are either too many changes to be tested in this PR or the code needs be rebased: (271 components likely to be affected)

@github-actions
Copy link
Contributor

↩️ There are either too many changes to be tested in this PR or the code needs be rebased: (271 components likely to be affected)

@github-actions
Copy link
Contributor

↩️ There are either too many changes to be tested in this PR or the code needs be rebased: (271 components likely to be affected)

@orpiske
Copy link
Contributor

orpiske commented May 24, 2023

@essobedo Here's the results:

Baseline (M3)

Benchmark                                Mode  Cnt  Score   Error  Units
EndpointResolveTest.testActionStatus_1   avgt   10  3.763 ± 0.004  us/op
EndpointResolveTest.testActionStatus_16  avgt   10  3.891 ± 0.003  us/op
EndpointResolveTest.testActionStatus_2   avgt   10  3.820 ± 0.004  us/op
EndpointResolveTest.testActionStatus_32  avgt   10  8.938 ± 0.080  us/op
EndpointResolveTest.testActionStatus_4   avgt   10  3.641 ± 0.006  us/op
EndpointResolveTest.testActionStatus_8   avgt   10  4.661 ± 0.022  us/op

Test

Benchmark                                Mode  Cnt  Score   Error  Units
EndpointResolveTest.testActionStatus_1   avgt   10  3.725 ± 0.001  us/op
EndpointResolveTest.testActionStatus_16  avgt   10  3.682 ± 0.001  us/op
EndpointResolveTest.testActionStatus_2   avgt   10  3.335 ± 0.004  us/op
EndpointResolveTest.testActionStatus_32  avgt   10  4.568 ± 0.023  us/op
EndpointResolveTest.testActionStatus_4   avgt   10  3.399 ± 0.001  us/op
EndpointResolveTest.testActionStatus_8   avgt   10  3.687 ± 0.005  us/op

Baseline

Benchmark                                          Mode  Cnt     Score    Error  Units
EndpointRegistryTest.testContainsExistentKey       avgt   10    17.566 ±  0.002  us/op
EndpointRegistryTest.testContainsNonExistentKey    avgt   10     5.199 ±  0.009  us/op
EndpointRegistryTest.testContainsNonExistentValue  avgt   10  1856.785 ±  0.740  us/op
EndpointRegistryTest.testDynamicSize               avgt   10     0.002 ±  0.001  us/op
EndpointRegistryTest.testIsDynamic                 avgt   10   942.753 ±  1.314  us/op
EndpointRegistryTest.testReadOnlyMap               avgt   10    18.959 ±  0.010  us/op
EndpointRegistryTest.testReadOnlyValues            avgt   10     5.730 ±  0.006  us/op

Test

Benchmark                                          Mode  Cnt     Score    Error  Units
EndpointRegistryTest.testContainsExistentKey       avgt   10    16.081 ±  0.016  us/op
EndpointRegistryTest.testContainsNonExistentKey    avgt   10     4.742 ±  0.001  us/op
EndpointRegistryTest.testContainsNonExistentValue  avgt   10  2997.418 ±  0.210  us/op
EndpointRegistryTest.testDynamicSize               avgt   10     0.003 ±  0.001  us/op
EndpointRegistryTest.testIsDynamic                 avgt   10  1035.011 ±  1.561  us/op
EndpointRegistryTest.testReadOnlyMap               avgt   10    44.540 ±  0.017  us/op
EndpointRegistryTest.testReadOnlyValues            avgt   10    13.574 ±  0.018  us/o

Baseline:

Benchmark                          Mode  Cnt  Score   Error  Units
EndpointCreationTest.testCreation  avgt   10  1.953 ± 0.006  ms/op

Test

Benchmark                          Mode  Cnt  Score   Error  Units
EndpointCreationTest.testCreation  avgt   10  1.787 ± 0.020  ms/op

Baseline

Benchmark                                                       Mode  Cnt     Score    Error  Units
EndpointRegistryScalabilityTest.testContainsNonExistentKey_2    avgt   10    16.835 ±  0.005  us/op
EndpointRegistryScalabilityTest.testContainsNonExistentKey_4    avgt   10    17.552 ±  0.006  us/op
EndpointRegistryScalabilityTest.testContainsNonExistentKey_8    avgt   10    16.861 ±  0.002  us/op
EndpointRegistryScalabilityTest.testContainsNonExistentValue_2  avgt   10  1868.717 ±  0.324  us/op
EndpointRegistryScalabilityTest.testContainsNonExistentValue_4  avgt   10  1844.561 ±  0.099  us/op
EndpointRegistryScalabilityTest.testContainsNonExistentValue_8  avgt   10  1874.376 ±  0.098  us/op
EndpointRegistryScalabilityTest.testDynamicSize_2               avgt   10     0.002 ±  0.001  us/op
EndpointRegistryScalabilityTest.testDynamicSize_4               avgt   10     0.002 ±  0.001  us/op
EndpointRegistryScalabilityTest.testDynamicSize_8               avgt   10     0.002 ±  0.001  us/op
EndpointRegistryScalabilityTest.testIsDynamic_2                 avgt   10   993.607 ±  0.969  us/op
EndpointRegistryScalabilityTest.testIsDynamic_4                 avgt   10   905.788 ±  0.292  us/op
EndpointRegistryScalabilityTest.testIsDynamic_8                 avgt   10   975.863 ±  1.586  us/op
EndpointRegistryScalabilityTest.testReadOnlyMap_2               avgt   10    18.860 ±  0.013  us/op
EndpointRegistryScalabilityTest.testReadOnlyMap_4               avgt   10    19.048 ±  0.107  us/op
EndpointRegistryScalabilityTest.testReadOnlyMap_8               avgt   10    19.607 ±  0.026  us/op
EndpointRegistryScalabilityTest.testReadOnlyValues_2            avgt   10     6.569 ±  0.018  us/op
EndpointRegistryScalabilityTest.testReadOnlyValues_4            avgt   10     6.508 ±  0.018  us/op
EndpointRegistryScalabilityTest.testReadOnlyValues_8            avgt   10     6.818 ±  0.005  us/op

Test

Benchmark                                                       Mode  Cnt     Score    Error  Units
EndpointRegistryScalabilityTest.testContainsNonExistentKey_2    avgt   10    16.683 ±  0.006  us/op
EndpointRegistryScalabilityTest.testContainsNonExistentKey_4    avgt   10    16.701 ±  0.010  us/op
EndpointRegistryScalabilityTest.testContainsNonExistentKey_8    avgt   10    17.285 ±  0.004  us/op
EndpointRegistryScalabilityTest.testContainsNonExistentValue_2  avgt   10  3024.244 ±  2.469  us/op
EndpointRegistryScalabilityTest.testContainsNonExistentValue_4  avgt   10  3022.183 ±  0.459  us/op
EndpointRegistryScalabilityTest.testContainsNonExistentValue_8  avgt   10  3023.758 ±  0.146  us/op
EndpointRegistryScalabilityTest.testDynamicSize_2               avgt   10     0.003 ±  0.001  us/op
EndpointRegistryScalabilityTest.testDynamicSize_4               avgt   10     0.003 ±  0.001  us/op
EndpointRegistryScalabilityTest.testDynamicSize_8               avgt   10     0.003 ±  0.001  us/op
EndpointRegistryScalabilityTest.testIsDynamic_2                 avgt   10  1054.665 ±  0.544  us/op
EndpointRegistryScalabilityTest.testIsDynamic_4                 avgt   10  1099.182 ±  2.231  us/op
EndpointRegistryScalabilityTest.testIsDynamic_8                 avgt   10  1055.774 ±  0.633  us/op
EndpointRegistryScalabilityTest.testReadOnlyMap_2               avgt   10    45.334 ±  0.051  us/op
EndpointRegistryScalabilityTest.testReadOnlyMap_4               avgt   10    45.599 ±  0.069  us/op
EndpointRegistryScalabilityTest.testReadOnlyMap_8               avgt   10    49.824 ±  0.049  us/op
EndpointRegistryScalabilityTest.testReadOnlyValues_2            avgt   10    15.052 ±  0.020  us/op
EndpointRegistryScalabilityTest.testReadOnlyValues_4            avgt   10    15.025 ±  0.013  us/op
EndpointRegistryScalabilityTest.testReadOnlyValues_8            avgt   10    15.407 ±  0.025  us/op

All in all, I think it's performing nicely! There's a few outliers (i.e.: like the testContainsNonExistentValue_X under contention), but in general LGTM.

@essobedo
Copy link
Contributor

Considering that the baseline is a non-thread-safe implementation that sounds good, thx @orpiske

@essobedo essobedo marked this pull request as ready for review May 24, 2023 13:13
@essobedo
Copy link
Contributor

@ben-manes thx, for your priceless feedback, anything else to add regarding this PR?

@essobedo essobedo changed the title CAMEL-19295: Experiment with sync LRUCache and test case that otherwi… CAMEL-19295: Basic thread-safe LRU cache May 24, 2023
@orpiske
Copy link
Contributor

orpiske commented May 24, 2023

@ben-manes thx, for your priceless feedback, anything else to add regarding this PR?

Indeed, thanks @ben-manes for the feedback!

Copy link
Contributor

@orpiske orpiske left a comment

Choose a reason for hiding this comment

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

Adding my +1. Nice one @essobedo!

@davsclaus
Copy link
Contributor Author

LGTM

Great collaboration guys and thanks for all the performance tests.

@ben-manes
Copy link

lgtm!

@essobedo
Copy link
Contributor

Ok let's merge it and see how the tests go

@essobedo essobedo merged commit 2f46ca6 into main May 24, 2023
@essobedo essobedo deleted the lru-sync branch May 24, 2023 15:44
@essobedo essobedo restored the lru-sync branch May 25, 2023 17:54
@essobedo essobedo deleted the lru-sync branch May 25, 2023 17:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants