summaryrefslogtreecommitdiff
path: root/test/697-checker-string-append
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2019-05-21 10:00:15 +0100
committer VladimĂ­r Marko <vmarko@google.com> 2023-01-03 12:31:57 +0000
commit41de45060710d64b671a0fa001ec187df221359d (patch)
treeacdd772258d4eb671f8aa00876988b3f59cc4d1f /test/697-checker-string-append
parent890b19bd625be5d0e4a876e3eb11b8b893fb0c13 (diff)
StringBuilder append pattern for float/double.
Results for added benchmarks on blueline-userdebug with cpu frequencies fxed at 1420800 (cpus 0-3; little) and 1459200 (cpus 4-7; big): 32-bit little (--variant=X32 --invoke-with 'taskset 0f') timeAppendStringAndDouble: ~1260ns -> ~970ns timeAppendStringAndFloat: ~1250ns -> ~940ns timeAppendStringAndHugeDouble: ~4700ns -> ~4690ns (noise) timeAppendStringAndHugeFloat: ~3400ns -> ~3300ns (noise) timeAppendStringDoubleStringAndFloat: ~1980ns -> ~1550ns 64-bit little (--variant=X64 --invoke-with 'taskset 0f') timeAppendStringAndDouble: ~1260ns -> ~970ns timeAppendStringAndFloat: ~1260ns -> ~940ns timeAppendStringAndHugeDouble: ~4700ns -> ~4800ns (noise) timeAppendStringAndHugeFloat: ~3300ns -> ~3400ns (noise) timeAppendStringDoubleStringAndFloat: ~1970ns -> ~1550ns 32-bit big (--variant=X32 --invoke-with 'taskset f0') timeAppendStringAndDouble: ~580ns -> ~450ns timeAppendStringAndFloat: ~590ns -> ~430ns timeAppendStringAndHugeDouble: ~2500ns -> ~2100ns (noise) timeAppendStringAndHugeFloat: ~1500ns -> ~1300ns (noise) timeAppendStringDoubleStringAndFloat: ~880ns -> ~730ns 64-bit big (--variant=X64 --invoke-with 'taskset f0') timeAppendStringAndDouble: ~590ns -> ~450ns timeAppendStringAndFloat: ~590ns -> ~430ns timeAppendStringAndHugeDouble: ~2300ns -> ~2300ns (noise) timeAppendStringAndHugeFloat: ~1500ns -> ~1300ns (noise) timeAppendStringDoubleStringAndFloat: ~870ns -> ~730ns The `timeAppendStringAnd{Double,Float)` benchmarks show very nice improvements, roughly 25% on both little and big cores. The `timeAppendStringDoubleStringAndFloat` also shows decent improvements, over 20% on little and over 15% on big cores. (These benchmarks test the best-case scenario for "before" as the StringBuilder's internal buffer is not reallocated.) The `testAppendStringAndHuge{Double,Float}` results are too noisy to draw any conclusions (especially on little cores but there is still too much noise on big cores as well). There are also small regressions for existing benchmarks `timeAppend{LongStrings,StringAndInt,Strings}` but these non-FP regressions may be mitigated after updating the ThinLTO profile. There is also an opportunity to optimize the calls back to managed code for known shorty (in this change we use "LD" and "LF") by using a dedicated stub instead of going through the generic invoke stub. Boot image size changes are insignificant (few matches). Test: Added tests to 697-checker-string-append Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Test: testrunner.py --target --optimizing Bug: 19575890 Change-Id: I9cf38c2d615a0a2b14255d18588a694d8870aae5
Diffstat (limited to 'test/697-checker-string-append')
-rw-r--r--test/697-checker-string-append/src/Main.java156
1 files changed, 156 insertions, 0 deletions
diff --git a/test/697-checker-string-append/src/Main.java b/test/697-checker-string-append/src/Main.java
index c63c328aa7..e35986a075 100644
--- a/test/697-checker-string-append/src/Main.java
+++ b/test/697-checker-string-append/src/Main.java
@@ -18,6 +18,9 @@ public class Main {
public static void main(String[] args) {
testAppendStringAndLong();
testAppendStringAndInt();
+ testAppendStringAndFloat();
+ testAppendStringAndDouble();
+ testAppendDoubleAndFloat();
testAppendStringAndString();
testMiscelaneous();
testNoArgs();
@@ -186,6 +189,159 @@ public class Main {
}
}
+ private static final String APPEND_FLOAT_PREFIX = "Float/";
+ private static final String[] APPEND_FLOAT_TEST_CASES = {
+ // We're testing only exact values here, i.e. values that do not require rounding.
+ "Float/1.0",
+ "Float/9.0",
+ "Float/10.0",
+ "Float/99.0",
+ "Float/100.0",
+ "Float/999.0",
+ "Float/1000.0",
+ "Float/9999.0",
+ "Float/10000.0",
+ "Float/99999.0",
+ "Float/100000.0",
+ "Float/999999.0",
+ "Float/1000000.0",
+ "Float/9999999.0",
+ "Float/1.0E7",
+ "Float/1.0E10",
+ "Float/-1.0",
+ "Float/-9.0",
+ "Float/-10.0",
+ "Float/-99.0",
+ "Float/-100.0",
+ "Float/-999.0",
+ "Float/-1000.0",
+ "Float/-9999.0",
+ "Float/-10000.0",
+ "Float/-99999.0",
+ "Float/-100000.0",
+ "Float/-999999.0",
+ "Float/-1000000.0",
+ "Float/-9999999.0",
+ "Float/-1.0E7",
+ "Float/-1.0E10",
+ "Float/0.25",
+ "Float/1.625",
+ "Float/9.3125",
+ "Float/-0.25",
+ "Float/-1.625",
+ "Float/-9.3125",
+ };
+
+ /// CHECK-START: java.lang.String Main.$noinline$appendStringAndFloat(java.lang.String, float) instruction_simplifier (before)
+ /// CHECK-NOT: StringBuilderAppend
+
+ /// CHECK-START: java.lang.String Main.$noinline$appendStringAndFloat(java.lang.String, float) instruction_simplifier (after)
+ /// CHECK: StringBuilderAppend
+ public static String $noinline$appendStringAndFloat(String s, float f) {
+ return new StringBuilder().append(s).append(f).toString();
+ }
+
+ public static void testAppendStringAndFloat() {
+ for (String expected : APPEND_FLOAT_TEST_CASES) {
+ float f = Float.valueOf(expected.substring(APPEND_FLOAT_PREFIX.length()));
+ String result = $noinline$appendStringAndFloat(APPEND_FLOAT_PREFIX, f);
+ assertEquals(expected, result);
+ }
+ // Special values.
+ assertEquals("Float/NaN", $noinline$appendStringAndFloat(APPEND_FLOAT_PREFIX, Float.NaN));
+ assertEquals("Float/Infinity",
+ $noinline$appendStringAndFloat(APPEND_FLOAT_PREFIX, Float.POSITIVE_INFINITY));
+ assertEquals("Float/-Infinity",
+ $noinline$appendStringAndFloat(APPEND_FLOAT_PREFIX, Float.NEGATIVE_INFINITY));
+ }
+
+ private static final String APPEND_DOUBLE_PREFIX = "Double/";
+ private static final String[] APPEND_DOUBLE_TEST_CASES = {
+ // We're testing only exact values here, i.e. values that do not require rounding.
+ "Double/1.0",
+ "Double/9.0",
+ "Double/10.0",
+ "Double/99.0",
+ "Double/100.0",
+ "Double/999.0",
+ "Double/1000.0",
+ "Double/9999.0",
+ "Double/10000.0",
+ "Double/99999.0",
+ "Double/100000.0",
+ "Double/999999.0",
+ "Double/1000000.0",
+ "Double/9999999.0",
+ "Double/1.0E7",
+ "Double/1.0E24",
+ "Double/-1.0",
+ "Double/-9.0",
+ "Double/-10.0",
+ "Double/-99.0",
+ "Double/-100.0",
+ "Double/-999.0",
+ "Double/-1000.0",
+ "Double/-9999.0",
+ "Double/-10000.0",
+ "Double/-99999.0",
+ "Double/-100000.0",
+ "Double/-999999.0",
+ "Double/-1000000.0",
+ "Double/-9999999.0",
+ "Double/-1.0E7",
+ "Double/-1.0E24",
+ "Double/0.25",
+ "Double/1.625",
+ "Double/9.3125",
+ "Double/-0.25",
+ "Double/-1.625",
+ "Double/-9.3125",
+ };
+
+ /// CHECK-START: java.lang.String Main.$noinline$appendStringAndDouble(java.lang.String, double) instruction_simplifier (before)
+ /// CHECK-NOT: StringBuilderAppend
+
+ /// CHECK-START: java.lang.String Main.$noinline$appendStringAndDouble(java.lang.String, double) instruction_simplifier (after)
+ /// CHECK: StringBuilderAppend
+ public static String $noinline$appendStringAndDouble(String s, double d) {
+ return new StringBuilder().append(s).append(d).toString();
+ }
+
+ public static void testAppendStringAndDouble() {
+ for (String expected : APPEND_DOUBLE_TEST_CASES) {
+ double f = Double.valueOf(expected.substring(APPEND_DOUBLE_PREFIX.length()));
+ String result = $noinline$appendStringAndDouble(APPEND_DOUBLE_PREFIX, f);
+ assertEquals(expected, result);
+ }
+ // Special values.
+ assertEquals(
+ "Double/NaN",
+ $noinline$appendStringAndDouble(APPEND_DOUBLE_PREFIX, Double.NaN));
+ assertEquals(
+ "Double/Infinity",
+ $noinline$appendStringAndDouble(APPEND_DOUBLE_PREFIX, Double.POSITIVE_INFINITY));
+ assertEquals(
+ "Double/-Infinity",
+ $noinline$appendStringAndDouble(APPEND_DOUBLE_PREFIX, Double.NEGATIVE_INFINITY));
+ }
+
+ /// CHECK-START: java.lang.String Main.$noinline$appendDoubleAndFloat(double, float) instruction_simplifier (before)
+ /// CHECK-NOT: StringBuilderAppend
+
+ /// CHECK-START: java.lang.String Main.$noinline$appendDoubleAndFloat(double, float) instruction_simplifier (after)
+ /// CHECK: StringBuilderAppend
+ public static String $noinline$appendDoubleAndFloat(double d, float f) {
+ return new StringBuilder().append(d).append(f).toString();
+ }
+
+ public static void testAppendDoubleAndFloat() {
+ assertEquals("1.50.325", $noinline$appendDoubleAndFloat(1.5, 0.325f));
+ assertEquals("1.5E170.3125", $noinline$appendDoubleAndFloat(1.5E17, 0.3125f));
+ assertEquals("1.0E8NaN", $noinline$appendDoubleAndFloat(1.0E8, Float.NaN));
+ assertEquals("Infinity0.5", $noinline$appendDoubleAndFloat(Double.POSITIVE_INFINITY, 0.5f));
+ assertEquals("2.5-Infinity", $noinline$appendDoubleAndFloat(2.5, Float.NEGATIVE_INFINITY));
+ }
+
public static String $noinline$appendStringAndString(String s1, String s2) {
return new StringBuilder().append(s1).append(s2).toString();
}