Java Performance Tips (So Code Camp San Diego 2014)
-
Upload
kai-chan -
Category
Technology
-
view
578 -
download
1
description
Transcript of Java Performance Tips (So Code Camp San Diego 2014)
Java Performance TipsKai Chan
SoCal Code Camp, June 2014
http://bit.ly/sdcodecamp2014java
This Talk
● is about…o several Java performance tips I have learned
● is NOT about…o language waro exhaustive listo really in-depth analysis
The Usual Caveats
● performance not your only concern● opportunity cost● premature optimization● test in your environment
String Manipulation
Ways to Concatenate Strings
● operators (+ and +=)● String’s concat method● StringBuilder
String s = a + b + c + d
same bytecode as:String s = new StringBuilder().append(a).append(b).append(c).append(d).toString()
String s = s + a + b + c + dString s += a + b + c + d
same bytecode as:
String s = new StringBuilder().append(s).append(a).append(b).append(c).append(d).toString()
String s = a.concat(b).concat(c).concat(d)
String s = s.concat(a).concat(b).concat(c).concat(d)
● not translated to use StringBuilder● only accepts String, can’t call method of null
StringBuilder result = new StringBuilder();while (stillRunning()) { … result.append(a); …}
String result = “”;while (stillRunning()) { … result += a; …}
String result = “”;while (stillRunning()) { … result = new StringBuilder() .append(s).append(a).toString(); …}
String result = “”;while (stillRunning()) { … result = new StringBuilder() .append(s).append(a).toString(); …}
copy characters from String to StringBuilder
copy characters from StringBuilder to String
create a new object
String Concatenation Example
● 100000 iterations● a 1 byte String appended per iteration● 100 KB of data appended
// initialize result variable…for (int i = 1; i <= 100000; i++) { // append 1-byte string to result}
+ or += operator
● iteration i:o copy (i - 1) bytes from String to StringBuildero append 1 byte to StringBuildero copy i bytes from StringBuilder to String
● total: copy 1.4 GB of data
String’s concat method
● iteration i:o copy (i - 1) bytes from the old String, plus 1 byte to
append with, to a new String● total: copy 672 MB of data
StringBuilder
● when needed to expando create a new buffer at least 2x as largeo copy data over
● to grow the buffer from 1 byte to >= 100000 bytes: copy 128 KB of data
● plus, copy 98 KB of data from outside StringBuilder
● total: copy 226 KB of data
CharSequence
● implemented byString, StringBuffer, StringBuilder
● methodso charAto lengtho subSequence
● does not define equals and hashCode
CharSequence
● Writero append(CharSequence)o append(CharSequence, int, int) // seq, start, end
● CharSequenceReader
public String getText() { StringBuilder result = new StringBuilder(); … return result.toString();}
copies all characters in the StringBuilder to a String
public CharSequence getText() { StringBuilder result = new StringBuilder(); … return result;}
Primitive Collections
● no direct supporto cannot have List<int>, Map<int, long>
● indirect support via boxingo “wrapper” classes, e.g. Integer, Longo can have List<Integer>, Map<Integer, Long>
● memory cost
Primitives Collection in Java
Object Metadata
● object’s class● lock/synchronization state● array size (if the object is an array)● total: ~8-12 bytes for 32-bit JVM
(more for 64-bit JVM)
metadata
element 999element 0
12 bytes 4 bytes 4 bytes 4 bytes
…
int[] with 1000 Elements
element 1
size = 4012 bytes
ArrayList<Integer> w/ 1000 Elements
metadata
size
8 bytes 4 bytes 4 or 8 bytes
metadata
value
metadata
value
metadata
value
8 bytes 8 bytes 8 bytes
4 bytes 4 bytes 4 bytes
size = 16028 bytes (if OOP size = 32 bits)size = 20032 bytes (if OOP size = 64 bits)
metadata
element 999element 0
12 bytes 4 or 8 bytes 4 or 8 bytes 4 or 8 bytes
…element 1
elementData
Map: Even More Overhead
● both key and value can be boxed primitives● some types of map half-full by design● e.g. HashMap<Integer, Integer>
Primitive Collection Implementations
● Troveo http://trove.starlight-systems.com/o does NOT implement Java’s Collection interfaceo iteration by callback object/method
Primitive Collection Implementations
● fastutilo http://fastutil.di.unimi.it/o type-specific maps, sets, listso sorted maps and setso implement Java’s Collection interfaceo primitive iteratorso latest version’s binary JAR file is 17 MB
Convert Primitive Array To List
● you have an int[]● some method only takes a List
(e.g. List<Integer>)● Arrays.asList(int[]): type mismatch
// someFunc takes a List, read-only// a: int[]list = new ArrayList<Integer>(a.length);for(int i = 0; i < a.length; i++){ list.add(a[i]);}someFunc(list);
// someFunc takes a List, read-only// a: int[]someFunc(Ints.asList(a));
● Ints.asList: returns a fixed-size list backed by the specified array
● Ints provided by Guava (from Google)
Regular Expression
Regular Expression
// input, regex: Stringinput.matches(regex)
does the following:
Pattern.compile(regex).matcher(input).matches()
while (stillRunning()) { … // str and regex: String if (str.matches(regex)) { … } …}
while (stillRunning()) { … // str and regex: String if (Pattern.compile(regex) .matcher(input) .matches()) { … } …}
while (stillRunning()) { … // str and regex: String if (Pattern.compile(regex) .matcher(input) .matches()) { … } …}
generate a Pattern object from the RE pattern(expensive)
java.util.regex.Pattern
● feature-rich● not the fastest
RE Benchmark
● Java Regular expression library benchmarkso http://tusker.org/regex/regex_benchmark.html
● many alternative implementations● speed and capability vary
BRICS Automaton
● http://www.brics.dk/automaton/● much faster than java.util.regex.Pattern● basic functionality● adopted by Lucene 4.x for RE query
Caching
Caching: Example Scenario
● calculate file checksums● calculation is expensive● lots of files● repeated calculations● solution: cache the checksum
o key: file path
Possible Solution: HashMap
● implement cache with HashMap<String, byte[]>
● problem:o assume cache will be “small enough”, or o need to remove entries (how?)
Possible Solution: WeakHashMap
● implement cache with WeakHashMap<String, byte[]>
● problem:o keys are weak referenceso if no strong reference on a key,
the entry is eligible for GC
Solution: Libraries
● Apache Commons Collectionso LRUMap classo LRU (least recently updated) cache algorithmo fixed max size
Solution: Libraries (cont.)
● Guavao CacheBuilder and Cache classeso accessible by multiple threadso eviction by: max size, access time, write time, weak
keys, weak values, soft valueso CacheLoader class: creates entry on demando remove listeners
Data Compression
Lossless Compression Today
● compression saves more space than ever● store more in faster medium (memory, SSD)● compression ! == slow anymore● new algorithms target high throughput
o > 300 MB/s compressiono > 1000 MB/s decompression
LZ4
● faster than Deflate with zlib● decent ratio● LZ4_HC
o slower compression speedo higher compression ratioo decoding side unchanged
● ported to Javao https://github.com/jpountz/lz4-java
Memory-Mapped File
Memory-Mapped File Intro
● MappedByteBuffer● content: memory-mapped region of a file● OS handles reading, writing, caching● can be used as persistent, shared memory
Memory-Mapped File Caveats
● file size limited by address spaceo 64-bit JVM: not an issueo 32-bit JVM: file size limited to <= 2 GB
● no “close function”o you can’t control when resources are freeo not suitable for opening many files at/around the
same time
Performance Measurement
VisualVM
● bundled with Java SE● local or remote (JMX) applications● monitor
o CPU usageo heap and PermGen usageo class and thread counts
VisualVM
● heap dumpo instance and size by classo biggest object by retain size
● sampler (fast)● profiler (slow)
Sampling Example
● run 4 methodso concatByAppendresult.append(x());o concatByConcatresult =
result.concat(x());o concatByPlusOperatorresult = result + x();o concatByPlusEqualOperatorresult += x();
● if same speed, each would get 25% CPU
Thanks for Coming!
● slides availableo http://bit.ly/sdcodecamp2014java
● please vote for my conference sessiono http://bit.ly/tvnews2014
● questions/feedbacko [email protected]
● questions?