java performance tips (so code camp san diego 2014)

Post on 26-May-2015

578 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

DESCRIPTION

Slides for my presentation at SoCal Code Camp, June 29, 2014 (http://www.socalcodecamp.com/socalcodecamp/session.aspx?sid=68942cd0-6714-4753-a218-20d4b48da07d)

TRANSCRIPT

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 kai@ssc.ucla.edu

● questions?

top related