JDK-7197183 : (str) String.substring and String.subsequence performance slower since 7u6
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 7u6,8
  • Priority: P4
  • Status: Closed
  • Resolution: Won't Fix
  • OS: linux_ubuntu
  • CPU: x86
  • Submitted: 2012-09-09
  • Updated: 2017-02-11
  • Resolved: 2015-01-29
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.7.0_07"
Java(TM) SE Runtime Environment (build 1.7.0_07-b10)
Java HotSpot(TM) Server VM (build 23.3-b01, mixed mode)

java version "1.7.0_06"
Java(TM) SE Runtime Environment (build 1.7.0_06-b24)
Java HotSpot(TM) Server VM (build 23.2-b09, mixed mode)




ADDITIONAL OS VERSION INFORMATION :
Linux 3.2.0-27-generic-pae #43-Ubuntu SMP Fri Jul 6 15:06:05 UTC 2012 i686 i686 i386 GNU/Linux


EXTRA RELEVANT SYSTEM CONFIGURATION :
Processor: Pentium(R) Dual-Core CPU E5700 @ 3.00GHz �� 2
Memory: 2 Gb

A DESCRIPTION OF THE PROBLEM :
The performance of the following two methods in the class "java.lang.String" is highly degraded (in JRE 7u6 and JRE 7u7). The reference for comparison is JRE 7u5.

1) substring(...)
2) subSequence(...)

My testing (using the code given below) shows that these functions require 4 times the duration (under 7u7 and 7u6) required under JRE 7u5.



REGRESSION.  Last worked in version 7

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Use the test program given further below. The program should be compiled and run under Java SE 7u5, 7u6, and 7u7. The test program prints out the time consumed by the functions "String.substring(...)" and "String.subSequence(...)". The performance under 7u7 and 7u6 is highly degraded as compared to the performance under 7u5. Note the performance numbers printed in the last two lines of each run shown below:

Running under 7u7:

$ java -version
java version "1.7.0_07"
Java(TM) SE Runtime Environment (build 1.7.0_07-b10)
Java HotSpot(TM) Server VM (build 23.3-b01, mixed mode)
$ java SubSeq
subSequence: 324033
substring: 272688

Running under 7u6:

$ ~/Desktop/Java-Reading/jre1.7.0_06/bin/java -version
java version "1.7.0_06"
Java(TM) SE Runtime Environment (build 1.7.0_06-b24)
Java HotSpot(TM) Server VM (build 23.2-b09, mixed mode)
$ ~/Desktop/Java-Reading/jre1.7.0_06/bin/java SubSeq
subSequence: 291457
substring: 282161

Running under 7u5:

$ ~/Desktop/Java-Reading/jre1.7.0_05/bin/java -version
java version "1.7.0_05"
Java(TM) SE Runtime Environment (build 1.7.0_05-b06)
Java HotSpot(TM) Server VM (build 23.1-b03, mixed mode)
$ ~/Desktop/Java-Reading/jre1.7.0_05/bin/java SubSeq
subSequence: 86591
substring: 68845






EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The performance under 7u6 and 7u7 should have been close to (or better than) that under 7u5.
ACTUAL -
The performance under 7u6 and 7u7 is approximately 4 times poorer than than under 7u5.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class SubSeq {
    public static void main(String[] args) {
        String sample =
            "The class String includes methods for examining " +
            "individual characters of the sequence, for comparing strings, " +
            "for searching strings, for extracting substrings, " +
            "and for creating a copy of a string with all " +
            "characters translated to uppercase or to lowercase. " +
            "Case mapping is based on the Unicode Standard " +
            "version specified by the Character class.";
        long t0 = System.nanoTime();
        for (int i = sample.length() - 1; i >= 0; --i) {
            sample.subSequence(i, sample.length());
        }
        long t = System.nanoTime() - t0;
        System.out.printf("subSequence: %d%n", t);
        t0 = System.nanoTime();
        for (int i = sample.length() - 1; i >= 0; --i) {
            sample.substring(i, sample.length());
        }
        t = System.nanoTime() - t0;
        System.out.printf("substring: %d%n", t);
    }
}

---------- END SOURCE ----------

Comments
I think that in many cases javax.swing.text.Segment can be used as the already implemented alternative.
23-01-2015

I think we've taken this as far as it can go. The consensus of the discussion in February of 2013 was that the suggested approach involved too much bending/breaking of specs, expectations, and behavior. In the end the benefits would not be worth the costs. A better approached would be to add something new. It's also possible that solutions could be provided outside the JDK itself. Some discussion along these lines have taken place here: http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-July/027838.html Further exploration of this problem space can be taken up under a new issue.
21-01-2015

A bit of discussion on this here: http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-February/014609.html It's not clear whether or not we should address the performance regression and if so, how.
12-04-2013

Proposed patch at: http://cr.openjdk.java.net/~mduigou/JDK-7197183/0/
17-02-2013