-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
In an earlier analysis the block-based sketch was significantly faster than the flat (uniform) one. This was independently confirmed by a C# and Go port, who also observed a 2x speed up. However, when recently adding this benchmark to the CI it showed it as a regression. Therefore some implicit compiler optimizations are now explicit, which allows the block-based sketch to match or exceed the flat-based performance. - We no longer rely on escape analysis to optimize away the method scoped arrays (count, index). These should have been stack allocated and broken into their components. - The arrays were meant to break a loop data dependency, but it is now faster to keep that. `Math.min` is a single cycle, branch-free instruction that the OOO pipeline seems to prefer. - `increment` is manually loop unrolled like the flat version, which shows a simiar speed up. - Previously, the flat benchmark version implemented the scaffolding interface directly, was pre-allocated, and the init guard was removed. This gave it a large advantage as it improved inlining, branch prediction, etc. The benchmark is now fair. - For jdk11 the block is always faster by at least 10M ops/s. In jdk23 the speedup only occurs as the table size increases, matching the expected gains from better cache effects. It is marginally slower on the small table size due to indexing differences. The differences are very hardware and compiler dependent, as there are wide variations when running on Intel, Arm, Java versions, and JVMs (Graal vs C2). The user effect will be noise since this was not a performance bottleneck due to the cache's overall design.
- Loading branch information
Showing
30 changed files
with
114 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,7 +28,7 @@ | |
* | ||
* @author [email protected] (Ben Manes) | ||
*/ | ||
public final class CountMinSketch<E> implements TinyLfuSketch<E> { | ||
public final class CountMinSketch<E> { | ||
|
||
/* | ||
* This class maintains a 4-bit CountMinSketch [1] with periodic aging to provide the popularity | ||
|
@@ -63,9 +63,27 @@ public final class CountMinSketch<E> implements TinyLfuSketch<E> { | |
long[] table; | ||
int size; | ||
|
||
public CountMinSketch(@NonNegative long maximumSize) { | ||
/** | ||
* Creates a lazily initialized frequency sketch, requiring {@link #ensureCapacity} be called | ||
* when the maximum size of the cache has been determined. | ||
*/ | ||
@SuppressWarnings({"NullAway.Init", "PMD.UnnecessaryConstructor"}) | ||
public CountMinSketch() {} | ||
|
||
/** | ||
* Initializes and increases the capacity of this <tt>FrequencySketch</tt> instance, if necessary, | ||
* to ensure that it can accurately estimate the popularity of elements given the maximum size of | ||
* the cache. This operation forgets all previous counts when resizing. | ||
* | ||
* @param maximumSize the maximum size of the cache | ||
*/ | ||
public void ensureCapacity(@NonNegative long maximumSize) { | ||
checkArgument(maximumSize >= 0); | ||
int maximum = (int) Math.min(maximumSize, Integer.MAX_VALUE >>> 1); | ||
if ((table != null) && (table.length >= maximum)) { | ||
return; | ||
} | ||
|
||
table = new long[(maximum == 0) ? 1 : IntMath.ceilingPowerOfTwo(maximum)]; | ||
tableMask = Math.max(0, table.length - 1); | ||
sampleSize = (maximumSize == 0) ? 10 : (10 * maximum); | ||
|
@@ -75,14 +93,25 @@ public CountMinSketch(@NonNegative long maximumSize) { | |
size = 0; | ||
} | ||
|
||
/** | ||
* Returns if the sketch has not yet been initialized, requiring that {@link #ensureCapacity} is | ||
* called before it begins to track frequencies. | ||
*/ | ||
public boolean isNotInitialized() { | ||
return (table == null); | ||
} | ||
|
||
/** | ||
* Returns the estimated number of occurrences of an element, up to the maximum (15). | ||
* | ||
* @param e the element to count occurrences of | ||
* @return the estimated number of occurrences of the element; possibly zero but never negative | ||
*/ | ||
@Override | ||
public @NonNegative int frequency(E e) { | ||
if (isNotInitialized()) { | ||
return 0; | ||
} | ||
|
||
int hash = spread(e.hashCode()); | ||
int start = (hash & 3) << 2; | ||
int frequency = Integer.MAX_VALUE; | ||
|
@@ -101,12 +130,15 @@ public CountMinSketch(@NonNegative long maximumSize) { | |
* | ||
* @param e the element to add | ||
*/ | ||
@Override | ||
public void increment(E e) { | ||
if (isNotInitialized()) { | ||
return; | ||
} | ||
|
||
int hash = spread(e.hashCode()); | ||
int start = (hash & 3) << 2; | ||
|
||
// Loop unrolling improves throughput | ||
// Loop unrolling improves throughput by 5m ops/s | ||
int index0 = indexOf(hash, 0); | ||
int index1 = indexOf(hash, 1); | ||
int index2 = indexOf(hash, 2); | ||
|
@@ -140,7 +172,6 @@ boolean incrementAt(int i, int j) { | |
} | ||
|
||
/** Reduces every counter by half of its original value. */ | ||
@Override | ||
public void reset() { | ||
int count = 0; | ||
for (int i = 0; i < table.length; i++) { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
examples/coalescing-bulkloader-reactor/gradle/libs.versions.toml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.