SlideShare a Scribd company logo
1 of 18
Java performance
(Strings)
Dreval Sergey (bolkimen@yahoo.com)
What is the most commonly used
class in java projects?
We use jmap tool from jdk to find the answer.
jmap -histo <java_app_pid> | head -n 14
Where <java_app_pid> - java application
process id (I have used pid of running tomcat
server)
The output of this command is:
num #instances #bytes class name
----------------------------------------------
1: 43101 18737736 [B
2: 61736 10054912 [C
3: 11598 5165024 [I
4: 58901 1413624 java.lang.String
5: 8514 749232 java.lang.reflect.Method
6: 21313 682016 java.util.HashMap$Node
7: 5286 549960 java.lang.Class
8: 7914 483944 [Ljava.lang.Object;
9: 9323 372920 java.util.HashMap$ValueIterator
10: 1814 320184 [Ljava.util.HashMap$Node;
11: 7862 314480 java.lang.ref.Finalizer
As we can see String is one of the common used classes in java projects and
takes a lot of memory. The most common operations performed with strings
is concatenation.
Strings
There are three variants of string concatenation:
1. String a = “Hello ” + “world”;
2. String b = new StringBuffer();
b.append(“Hello ”);
b.append(“world”).toString();
3. String c = “Hello ”.concat(“world”);
Let's look to them closer and try to compare...
stringA + stringB
There are two common possibilities to concatenate strings using '+'
sign:
1. String s1 = “STRING_VAL1” + “STRING_VAL2”;
2. String s2 = “STRING_VAL1” + STRING_VARIABLE;
We need to view generated bytecode by javap from jdk to
compare them:
javap -c SomeJava.class
For the first expression it looks like this.
Source:
String q = "Hello " + "world";
Bytecode:
public static void main(java.lang.String[]) throws java.lang.Exception;
Code:
0: ldc #3 // String Hello world
2: astore_1
3: return
For the second expression.
Source:
String hello = "Hello ";
String result = hello + "world";
Bytecode:
public static void main(java.lang.String[]) throws java.lang.Exception;
Code:
0: ldc #3 // String Hello
2: astore_1
3: new #4 // class java/lang/StringBuilder
6: dup
7: invokespecial #5 // Method java/lang/StringBuilder."<init>":()V
10: aload_1
11: invokevirtual #6 // Method java/lang/StringBuilder.append
14: ldc #7 // String world
16: invokevirtual #6 // Method java/lang/StringBuilder.append
19: invokevirtual #8 // Method java/lang/StringBuilder.toString
22: astore_2
23: return
If you try to concatenate two or more constant
strings then java compiler do this operation in
compile time:
String s = “Hello ” + “world” + “...”;
In other cases will be used explicitly or implicitly
StringBuilder and String.concat() method.
StringBuffer is also possible for multithreading
applications, but we examine only first two in bold.
Let's decide which of them better
We will create two microbenchmark tests to find
out which is better StringBuilder or String.concat:
@State(Scope.Thread)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class StringOpts {
@Benchmark
@BenchmarkMode({Mode.AverageTime})
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public void concat_() {
String s1 = "Hello";
String s2 = s1.concat(" world");
}
@Benchmark
@BenchmarkMode({Mode.AverageTime})
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public void append_() {
StringBuilder s1 = new StringBuilder("Hello");
String s2 = s1.append(" world").toString();
}
}
When benchmark had been finished we got such
result:
# Run complete. Total time: 00:00:12
Benchmark Mode Samples Score Error Units
t.StringOpts.append_ avgt 1 0.007 ± NaN us/op
t.StringOpts.concat_ avgt 1 0.010 ± NaN us/op
Where you can see that StringBuilder.append is
faster than String.concat function. When you need
concatenate only two strings in some cases you
can prefer String.concat because this generates
less objects than when you use StringBuilder.
String comparison
Comparison is the second common operation with
strings in java. Let's find out which of this four
functions are faster than other:
1. String.intern()
2. String.equals()
3. String.equalsIgnoreCase()
4. String.compareTo()
I decide to use in my benchmark array of 1000
random strings and compare elements from first
path (0..499) with elements from second path
(500..999):
@Setup
public void prepare() {
testStringsPool = new String[1000];
for (int i = 0; i < testStringsPool.length; i++) {
int customLength = rnd.nextInt();
if (customLength < 0) {
customLength *= -1;
}
testStringsPool[i] = randomString(customLength % 20 + 10);
}
}
Here are my benchmark functions without
annotations:
public void intern_() {
for (int i = 0; i < testStringsPool.length / 2; i++) {
if (testStringsPool[i].intern() ==
testStringsPool[testStringsPool.length - i – 1].intern());
}
}
public void equals_() {
for (int i = 0; i < testStringsPool.length / 2; i++) {
if (testStringsPool[i].equals(
testStringsPool[testStringsPool.length - i – 1]));
}
}
public void compareTo_() {
for (int i = 0; i < testStringsPool.length / 2; i++) {
if (testStringsPool[i].compareTo(
testStringsPool[testStringsPool.length - i - 1]) == 0);
}
}
public void equalsIgnoreCase_() {
for (int i = 0; i < testStringsPool.length / 2; i++) {
If(testStringsPool[i].equalsIgnoreCase(
testStringsPool[testStringsPool.length - i - 1]));
}
}
When we run those benchmark tests, we get
something similar like this:
# Run complete. Total time: 00:00:25
Benchmark Mode Samples Score Error Units
t.StringOpts.compareTo_ avgt 1 0.270 ± NaN us/op
t.StringOpts.equalsIgnoreCase_ avgt 1 1.323 ± NaN us/op
t.StringOpts.equals_ avgt 1 0.348 ± NaN us/op
t.StringOpts.intern_ avgt 1 148.612 ± NaN us/op
The winner is String.compareTo function
Conclusion for string comparison
1. compareTo – is the fastest because it
operates with parameter of String class without
additional checking for type safety
2. equals – a bit slower by checking input
parameter for the same type (String)
3. equalsIgnoreCase – more slower because all
the characters are converted to uppercase in
both strings
4. intern – the slowest. But when you need to
work with many identical strings it can help you
to reduce memory usage.
Thank for your attention!
Any questions?

More Related Content

What's hot

Lecture 2, c++(complete reference,herbet sheidt)chapter-12
Lecture 2, c++(complete reference,herbet sheidt)chapter-12Lecture 2, c++(complete reference,herbet sheidt)chapter-12
Lecture 2, c++(complete reference,herbet sheidt)chapter-12Abu Saleh
 
Pj01 4-operators and control flow
Pj01 4-operators and control flowPj01 4-operators and control flow
Pj01 4-operators and control flowSasidharaRaoMarrapu
 
An introduction to Google test framework
An introduction to Google test frameworkAn introduction to Google test framework
An introduction to Google test frameworkAbner Chih Yi Huang
 
Understanding Javascript Engine to Code Better
Understanding Javascript Engine to Code BetterUnderstanding Javascript Engine to Code Better
Understanding Javascript Engine to Code BetterIhsan Fauzi Rahman
 
Annotation Processing - Demystifying Java's Dark Arts
Annotation Processing - Demystifying Java's Dark ArtsAnnotation Processing - Demystifying Java's Dark Arts
Annotation Processing - Demystifying Java's Dark ArtsJames Kirkbride
 
Mockito with a hint of PowerMock
Mockito with a hint of PowerMockMockito with a hint of PowerMock
Mockito with a hint of PowerMockYing Zhang
 
ConFess Vienna 2015 - Metaprogramming with Groovy
ConFess Vienna 2015 - Metaprogramming with GroovyConFess Vienna 2015 - Metaprogramming with Groovy
ConFess Vienna 2015 - Metaprogramming with GroovyIván López Martín
 
A Re-Introduction to JavaScript
A Re-Introduction to JavaScriptA Re-Introduction to JavaScript
A Re-Introduction to JavaScriptSimon Willison
 
Testers guide to unit testing
Testers guide to unit testingTesters guide to unit testing
Testers guide to unit testingCraig Risi
 
Mutation Testing
Mutation TestingMutation Testing
Mutation Testing10Pines
 

What's hot (20)

Simple Java Programs
Simple Java ProgramsSimple Java Programs
Simple Java Programs
 
Java Programming - 03 java control flow
Java Programming - 03 java control flowJava Programming - 03 java control flow
Java Programming - 03 java control flow
 
Lecture 2, c++(complete reference,herbet sheidt)chapter-12
Lecture 2, c++(complete reference,herbet sheidt)chapter-12Lecture 2, c++(complete reference,herbet sheidt)chapter-12
Lecture 2, c++(complete reference,herbet sheidt)chapter-12
 
CODEsign 2015
CODEsign 2015CODEsign 2015
CODEsign 2015
 
JVM Mechanics
JVM MechanicsJVM Mechanics
JVM Mechanics
 
Java programs
Java programsJava programs
Java programs
 
Pj01 4-operators and control flow
Pj01 4-operators and control flowPj01 4-operators and control flow
Pj01 4-operators and control flow
 
An introduction to Google test framework
An introduction to Google test frameworkAn introduction to Google test framework
An introduction to Google test framework
 
Java lab 2
Java lab 2Java lab 2
Java lab 2
 
Understanding Javascript Engine to Code Better
Understanding Javascript Engine to Code BetterUnderstanding Javascript Engine to Code Better
Understanding Javascript Engine to Code Better
 
Java operators
Java operatorsJava operators
Java operators
 
Annotation Processing - Demystifying Java's Dark Arts
Annotation Processing - Demystifying Java's Dark ArtsAnnotation Processing - Demystifying Java's Dark Arts
Annotation Processing - Demystifying Java's Dark Arts
 
Java Generics
Java GenericsJava Generics
Java Generics
 
Mockito with a hint of PowerMock
Mockito with a hint of PowerMockMockito with a hint of PowerMock
Mockito with a hint of PowerMock
 
Easy mockppt
Easy mockpptEasy mockppt
Easy mockppt
 
ConFess Vienna 2015 - Metaprogramming with Groovy
ConFess Vienna 2015 - Metaprogramming with GroovyConFess Vienna 2015 - Metaprogramming with Groovy
ConFess Vienna 2015 - Metaprogramming with Groovy
 
A Re-Introduction to JavaScript
A Re-Introduction to JavaScriptA Re-Introduction to JavaScript
A Re-Introduction to JavaScript
 
Chapter 2 Java Methods
Chapter 2 Java MethodsChapter 2 Java Methods
Chapter 2 Java Methods
 
Testers guide to unit testing
Testers guide to unit testingTesters guide to unit testing
Testers guide to unit testing
 
Mutation Testing
Mutation TestingMutation Testing
Mutation Testing
 

Similar to Java performance

Improving Android Performance at Droidcon UK 2014
Improving Android Performance at Droidcon UK 2014Improving Android Performance at Droidcon UK 2014
Improving Android Performance at Droidcon UK 2014Raimon Ràfols
 
Grails unit testing
Grails unit testingGrails unit testing
Grails unit testingpleeps
 
Improving Java performance at JBCNConf 2015
Improving Java performance at JBCNConf 2015Improving Java performance at JBCNConf 2015
Improving Java performance at JBCNConf 2015Raimon Ràfols
 
Java fundamentals
Java fundamentalsJava fundamentals
Java fundamentalsHCMUTE
 
4CS4-25-Java-Lab-Manual.pdf
4CS4-25-Java-Lab-Manual.pdf4CS4-25-Java-Lab-Manual.pdf
4CS4-25-Java-Lab-Manual.pdfamitbhachne
 
Tdd with python unittest for embedded c
Tdd with python unittest for embedded cTdd with python unittest for embedded c
Tdd with python unittest for embedded cBenux Wei
 
Inside the JVM - Follow the white rabbit! / Breizh JUG
Inside the JVM - Follow the white rabbit! / Breizh JUGInside the JVM - Follow the white rabbit! / Breizh JUG
Inside the JVM - Follow the white rabbit! / Breizh JUGSylvain Wallez
 
Intro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiIntro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiRan Mizrahi
 
Parallel Programming With Dot Net
Parallel Programming With Dot NetParallel Programming With Dot Net
Parallel Programming With Dot NetNeeraj Kaushik
 

Similar to Java performance (20)

Improving Android Performance at Droidcon UK 2014
Improving Android Performance at Droidcon UK 2014Improving Android Performance at Droidcon UK 2014
Improving Android Performance at Droidcon UK 2014
 
Java Fundamentals
Java FundamentalsJava Fundamentals
Java Fundamentals
 
00_Introduction to Java.ppt
00_Introduction to Java.ppt00_Introduction to Java.ppt
00_Introduction to Java.ppt
 
Grails unit testing
Grails unit testingGrails unit testing
Grails unit testing
 
Java tut1
Java tut1Java tut1
Java tut1
 
Tutorial java
Tutorial javaTutorial java
Tutorial java
 
Java Tut1
Java Tut1Java Tut1
Java Tut1
 
Java Tutorial
Java TutorialJava Tutorial
Java Tutorial
 
Improving Java performance at JBCNConf 2015
Improving Java performance at JBCNConf 2015Improving Java performance at JBCNConf 2015
Improving Java performance at JBCNConf 2015
 
Java For Automation
Java   For AutomationJava   For Automation
Java For Automation
 
Java fundamentals
Java fundamentalsJava fundamentals
Java fundamentals
 
4CS4-25-Java-Lab-Manual.pdf
4CS4-25-Java-Lab-Manual.pdf4CS4-25-Java-Lab-Manual.pdf
4CS4-25-Java-Lab-Manual.pdf
 
Tdd with python unittest for embedded c
Tdd with python unittest for embedded cTdd with python unittest for embedded c
Tdd with python unittest for embedded c
 
JAVA_BASICS.ppt
JAVA_BASICS.pptJAVA_BASICS.ppt
JAVA_BASICS.ppt
 
JavaProgrammingManual
JavaProgrammingManualJavaProgrammingManual
JavaProgrammingManual
 
Loop
LoopLoop
Loop
 
Java Lab Manual
Java Lab ManualJava Lab Manual
Java Lab Manual
 
Inside the JVM - Follow the white rabbit! / Breizh JUG
Inside the JVM - Follow the white rabbit! / Breizh JUGInside the JVM - Follow the white rabbit! / Breizh JUG
Inside the JVM - Follow the white rabbit! / Breizh JUG
 
Intro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiIntro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran Mizrahi
 
Parallel Programming With Dot Net
Parallel Programming With Dot NetParallel Programming With Dot Net
Parallel Programming With Dot Net
 

Java performance

  • 2. What is the most commonly used class in java projects? We use jmap tool from jdk to find the answer. jmap -histo <java_app_pid> | head -n 14 Where <java_app_pid> - java application process id (I have used pid of running tomcat server)
  • 3. The output of this command is: num #instances #bytes class name ---------------------------------------------- 1: 43101 18737736 [B 2: 61736 10054912 [C 3: 11598 5165024 [I 4: 58901 1413624 java.lang.String 5: 8514 749232 java.lang.reflect.Method 6: 21313 682016 java.util.HashMap$Node 7: 5286 549960 java.lang.Class 8: 7914 483944 [Ljava.lang.Object; 9: 9323 372920 java.util.HashMap$ValueIterator 10: 1814 320184 [Ljava.util.HashMap$Node; 11: 7862 314480 java.lang.ref.Finalizer As we can see String is one of the common used classes in java projects and takes a lot of memory. The most common operations performed with strings is concatenation.
  • 4. Strings There are three variants of string concatenation: 1. String a = “Hello ” + “world”; 2. String b = new StringBuffer(); b.append(“Hello ”); b.append(“world”).toString(); 3. String c = “Hello ”.concat(“world”); Let's look to them closer and try to compare...
  • 5. stringA + stringB There are two common possibilities to concatenate strings using '+' sign: 1. String s1 = “STRING_VAL1” + “STRING_VAL2”; 2. String s2 = “STRING_VAL1” + STRING_VARIABLE; We need to view generated bytecode by javap from jdk to compare them: javap -c SomeJava.class
  • 6. For the first expression it looks like this. Source: String q = "Hello " + "world"; Bytecode: public static void main(java.lang.String[]) throws java.lang.Exception; Code: 0: ldc #3 // String Hello world 2: astore_1 3: return
  • 7. For the second expression. Source: String hello = "Hello "; String result = hello + "world"; Bytecode: public static void main(java.lang.String[]) throws java.lang.Exception; Code: 0: ldc #3 // String Hello 2: astore_1 3: new #4 // class java/lang/StringBuilder 6: dup 7: invokespecial #5 // Method java/lang/StringBuilder."<init>":()V 10: aload_1 11: invokevirtual #6 // Method java/lang/StringBuilder.append 14: ldc #7 // String world 16: invokevirtual #6 // Method java/lang/StringBuilder.append 19: invokevirtual #8 // Method java/lang/StringBuilder.toString 22: astore_2 23: return
  • 8. If you try to concatenate two or more constant strings then java compiler do this operation in compile time: String s = “Hello ” + “world” + “...”; In other cases will be used explicitly or implicitly StringBuilder and String.concat() method. StringBuffer is also possible for multithreading applications, but we examine only first two in bold. Let's decide which of them better
  • 9.
  • 10. We will create two microbenchmark tests to find out which is better StringBuilder or String.concat: @State(Scope.Thread) @OutputTimeUnit(TimeUnit.NANOSECONDS) public class StringOpts { @Benchmark @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.MICROSECONDS) public void concat_() { String s1 = "Hello"; String s2 = s1.concat(" world"); } @Benchmark @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.MICROSECONDS) public void append_() { StringBuilder s1 = new StringBuilder("Hello"); String s2 = s1.append(" world").toString(); } }
  • 11. When benchmark had been finished we got such result: # Run complete. Total time: 00:00:12 Benchmark Mode Samples Score Error Units t.StringOpts.append_ avgt 1 0.007 ± NaN us/op t.StringOpts.concat_ avgt 1 0.010 ± NaN us/op Where you can see that StringBuilder.append is faster than String.concat function. When you need concatenate only two strings in some cases you can prefer String.concat because this generates less objects than when you use StringBuilder.
  • 12. String comparison Comparison is the second common operation with strings in java. Let's find out which of this four functions are faster than other: 1. String.intern() 2. String.equals() 3. String.equalsIgnoreCase() 4. String.compareTo()
  • 13. I decide to use in my benchmark array of 1000 random strings and compare elements from first path (0..499) with elements from second path (500..999): @Setup public void prepare() { testStringsPool = new String[1000]; for (int i = 0; i < testStringsPool.length; i++) { int customLength = rnd.nextInt(); if (customLength < 0) { customLength *= -1; } testStringsPool[i] = randomString(customLength % 20 + 10); } }
  • 14. Here are my benchmark functions without annotations: public void intern_() { for (int i = 0; i < testStringsPool.length / 2; i++) { if (testStringsPool[i].intern() == testStringsPool[testStringsPool.length - i – 1].intern()); } } public void equals_() { for (int i = 0; i < testStringsPool.length / 2; i++) { if (testStringsPool[i].equals( testStringsPool[testStringsPool.length - i – 1])); } }
  • 15. public void compareTo_() { for (int i = 0; i < testStringsPool.length / 2; i++) { if (testStringsPool[i].compareTo( testStringsPool[testStringsPool.length - i - 1]) == 0); } } public void equalsIgnoreCase_() { for (int i = 0; i < testStringsPool.length / 2; i++) { If(testStringsPool[i].equalsIgnoreCase( testStringsPool[testStringsPool.length - i - 1])); } }
  • 16. When we run those benchmark tests, we get something similar like this: # Run complete. Total time: 00:00:25 Benchmark Mode Samples Score Error Units t.StringOpts.compareTo_ avgt 1 0.270 ± NaN us/op t.StringOpts.equalsIgnoreCase_ avgt 1 1.323 ± NaN us/op t.StringOpts.equals_ avgt 1 0.348 ± NaN us/op t.StringOpts.intern_ avgt 1 148.612 ± NaN us/op The winner is String.compareTo function
  • 17. Conclusion for string comparison 1. compareTo – is the fastest because it operates with parameter of String class without additional checking for type safety 2. equals – a bit slower by checking input parameter for the same type (String) 3. equalsIgnoreCase – more slower because all the characters are converted to uppercase in both strings 4. intern – the slowest. But when you need to work with many identical strings it can help you to reduce memory usage.
  • 18. Thank for your attention! Any questions?