This way is faster, saving about 8% on the microbenchmark that rounds to the nearest month. That is in the hot path for `date_histogram` which is a very popular aggregation so it seems worth it to at least try and speed it up a little. Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
66b3e89482
commit
dfd502f9ca
|
@ -63,3 +63,29 @@ To get realistic results, you should exercise care when running benchmarks. Here
|
||||||
* Blindly believe the numbers that your microbenchmark produces but verify them by measuring e.g. with `-prof perfasm`.
|
* Blindly believe the numbers that your microbenchmark produces but verify them by measuring e.g. with `-prof perfasm`.
|
||||||
* Run more threads than your number of CPU cores (in case you run multi-threaded microbenchmarks).
|
* Run more threads than your number of CPU cores (in case you run multi-threaded microbenchmarks).
|
||||||
* Look only at the `Score` column and ignore `Error`. Instead take countermeasures to keep `Error` low / variance explainable.
|
* Look only at the `Score` column and ignore `Error`. Instead take countermeasures to keep `Error` low / variance explainable.
|
||||||
|
|
||||||
|
## Disassembling
|
||||||
|
|
||||||
|
Disassembling is fun! Maybe not always useful, but always fun! Generally, you'll want to install `perf` and FCML's `hsdis`.
|
||||||
|
`perf` is generally available via `apg-get install perf` or `pacman -S perf`. FCML is a little more involved. This worked
|
||||||
|
on 2020-08-01:
|
||||||
|
|
||||||
|
```
|
||||||
|
wget https://github.com/swojtasiak/fcml-lib/releases/download/v1.2.2/fcml-1.2.2.tar.gz
|
||||||
|
tar xf fcml*
|
||||||
|
cd fcml*
|
||||||
|
./configure
|
||||||
|
make
|
||||||
|
cd example/hsdis
|
||||||
|
make
|
||||||
|
cp .libs/libhsdis.so.0.0.0
|
||||||
|
sudo cp .libs/libhsdis.so.0.0.0 /usr/lib/jvm/java-14-adoptopenjdk/lib/hsdis-amd64.so
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to disassemble a single method do something like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
gradlew -p benchmarks run --args ' MemoryStatsBenchmark -jvmArgs "-XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*.yourMethodName -XX:PrintAssemblyOptions=intel"
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want `perf` to find the hot methods for you then do add `-prof:perfasm`.
|
||||||
|
|
|
@ -92,8 +92,27 @@ class DateUtilsRounding {
|
||||||
return (year * 365L + (leapYears - DAYS_0000_TO_1970)) * MILLIS_PER_DAY; // millis per day
|
return (year * 365L + (leapYears - DAYS_0000_TO_1970)) * MILLIS_PER_DAY; // millis per day
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isLeapYear(final int year) {
|
static boolean isLeapYear(final int year) {
|
||||||
return ((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0);
|
// Joda had
|
||||||
|
// return ((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0);
|
||||||
|
// But we've replaced that with this:
|
||||||
|
if ((year & 3) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (year % 100 != 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return ((year / 100) & 3) == 0;
|
||||||
|
/*
|
||||||
|
* It is a little faster because it saves a division. We don't have good
|
||||||
|
* measurements for this method on its own, but this change speeds up
|
||||||
|
* rounding the nearest month by about 8%.
|
||||||
|
*
|
||||||
|
* Note: If you decompile this method to x86 assembly you won't see the
|
||||||
|
* division you'd expect from % 100 and / 100. Instead you'll see a funny
|
||||||
|
* sequence of bit twiddling operations which the jvm thinks is faster.
|
||||||
|
* Division is slow so it almost certainly is.
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final long AVERAGE_MILLIS_PER_YEAR_DIVIDED_BY_TWO = MILLIS_PER_YEAR / 2;
|
private static final long AVERAGE_MILLIS_PER_YEAR_DIVIDED_BY_TWO = MILLIS_PER_YEAR / 2;
|
||||||
|
|
|
@ -46,4 +46,14 @@ public class DateUtilsRoundingTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testIsLeapYear() {
|
||||||
|
assertTrue(DateUtilsRounding.isLeapYear(2004));
|
||||||
|
assertTrue(DateUtilsRounding.isLeapYear(2000));
|
||||||
|
assertTrue(DateUtilsRounding.isLeapYear(1996));
|
||||||
|
assertFalse(DateUtilsRounding.isLeapYear(2001));
|
||||||
|
assertFalse(DateUtilsRounding.isLeapYear(1900));
|
||||||
|
assertFalse(DateUtilsRounding.isLeapYear(-1000));
|
||||||
|
assertTrue(DateUtilsRounding.isLeapYear(-996));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue