mirror of
https://github.com/openjdk/jdk.git
synced 2026-06-11 13:05:45 +00:00
128 lines
4.3 KiB
Java
128 lines
4.3 KiB
Java
/*
|
|
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
|
* Copyright 2026 Arm Limited and/or its affiliates.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*/
|
|
package org.openjdk.bench.java.lang;
|
|
|
|
import org.openjdk.jmh.annotations.*;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
/*
|
|
* This benchmark naively explores String::equals performance
|
|
*/
|
|
@BenchmarkMode(Mode.AverageTime)
|
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
|
@State(Scope.Thread)
|
|
@Warmup(iterations = 5, time = 1)
|
|
@Measurement(iterations = 5, time = 1)
|
|
@Fork(value = 3)
|
|
public class StringEquals {
|
|
|
|
public String test = new String("0123456789");
|
|
public String test2 = new String("tgntogjnrognagronagroangroarngorngaorng");
|
|
public String test3 = new String(test); // equal to test, but not same
|
|
public String test4 = new String("0123\u01FF");
|
|
public String test5 = new String(test4); // equal to test4, but not same
|
|
public String test6 = new String("0123456780");
|
|
public String test7 = new String("0123\u01FE");
|
|
// string with parameterizable size
|
|
public String test8;
|
|
// same chars as test8, but different object; forces the intrinsic to read
|
|
// the entire string to check equality
|
|
public String test9;
|
|
// same chars as test8, except at length + diff_pos; set diff_pos to the
|
|
// worst case for the intrinsic being tested (usually -1, but could be -9
|
|
// if the intrinsic reads the last 8B first, or -length if the intrinsic
|
|
// reads the string backwards
|
|
public String test10;
|
|
|
|
@Param({"30"}) // can be used at runtime to define a length sweep
|
|
public int size;
|
|
|
|
@Param({"-1"}) // set to the worst location for the intrinsic under test
|
|
public int diff_pos;
|
|
|
|
@Setup
|
|
public void setup() {
|
|
if (size > 0) {
|
|
test8 = "a".repeat(size);
|
|
// NOTE 1: can't do test9 = new String(test8) or they'll share byte
|
|
// arrays, which improves cache hit rate of the equal-string case
|
|
test9 = "a".repeat(size);
|
|
StringBuilder sb = new StringBuilder("a".repeat(size));
|
|
sb.setCharAt(Math.max(test8.length() + diff_pos, 0), 'b');
|
|
test10 = sb.toString();
|
|
}
|
|
else {
|
|
// NOTE 2: can't use "a".repeat(0) or it returns the "" literal,
|
|
// which will early-exit from String.equals()
|
|
// NOTE 3: can't use no-arg String ctor or they'll share the byte
|
|
// array of the "" literal, which improves cache hit rate for
|
|
// intrinsics that read backwards into the object header
|
|
test8 = new String(new char [] {});
|
|
test9 = new String(new char [] {});
|
|
test10 = new String(new char [] {});
|
|
}
|
|
}
|
|
|
|
@Benchmark
|
|
public boolean different() {
|
|
return test.equals(test2);
|
|
}
|
|
|
|
@Benchmark
|
|
public boolean equal() {
|
|
return test.equals(test3);
|
|
}
|
|
|
|
@Benchmark
|
|
public boolean differentParam() {
|
|
return test8.equals(test10);
|
|
}
|
|
|
|
@Benchmark
|
|
public boolean equalParam() {
|
|
return test8.equals(test9);
|
|
}
|
|
|
|
@Benchmark
|
|
public boolean almostEqual() {
|
|
return test.equals(test6);
|
|
}
|
|
|
|
@Benchmark
|
|
public boolean almostEqualUTF16() {
|
|
return test4.equals(test7);
|
|
}
|
|
|
|
@Benchmark
|
|
public boolean differentCoders() {
|
|
return test.equals(test4);
|
|
}
|
|
|
|
@Benchmark
|
|
public boolean equalsUTF16() {
|
|
return test5.equals(test4);
|
|
}
|
|
}
|
|
|