30 November 2017

Java Performance

This is a summary post of good practices (many easy) to improve performance in your Java code:
  1. use Apache commons-lang StringUtils.replace() instead String.replace(). The big difference is because Java replace() uses regexp which makes it more expensive immediately.
  2. avoid regexp if possible (many times we use regexp and meanwhile a String.indexof() is enough).  also, Apache commons lang: StringUtils.replace("hola\nmundo\n", "\n", "");
  3. Compile once a Regexp Pattern:  Pattern pattern_dst = Pattern.compile("destinationAddress\\\"\\:\\\"[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+\\\"");
  4. Apache commons lang, now has separated packages for regexp methods, such us, replaceall().
  5. on the same, String.split also has issues when it's not a simple character the splitter
  6. avoid using Java7 UUID (there are other faster libraries for it) (randomness trends to be slow).
    https://github.com/cowtowncoder/java-uuid-generator
    https://github.com/jchambers/fast-uuid    (* this looks interesting)
    https://github.com/codahale/fast-uuid
  7. Asynchronous Logging Parameterized Messages (log4j2) (Ring buffer - LMAX Disruptor)
    Many logging libraries offer an API for logging parameterized messages. This enables application code to look something like this:
    logger.debug("Entry number: {} is {}", i, entry[i]);
    without API:
    if (logger.isDebugEnabled()) {
        logger.debug("Entry number: " + i + " is " + entry[i].toString());
    }
    The best solution is placeholders and if{}
    if (logger.isDebugEnabled()) {
        logger.debug("Entry number: {} is {}", i, entry[i]);
    } 
    lambda java8:
    logger.trace("Some long-running operation returned {}", () -> expensiveOperation());
  8. Jasper Reports has a lazy loading at init() :
    JasperReportsContext jasperReportsContext = new SimpleJasperReportsContext();
            LocalJasperReportsContext localJasperReportsContext = new LocalJasperReportsContext(jasperReportsContext);
            localJasperReportsContext.setClassLoader(this.getClass().getClassLoader());
  9. StringBuilder or StringBuffer over String (for concatenation)
  10. Primitive over wrapper, such us, Integer, Double etc, ie:
    The Integer class wraps a value of the primitive type int in an object. An object of type Integer contains a single field whose type is int.
    If you need an object instead, then use Integer.valueOf(), Long.valueOf()
  11. Sorted of sorted List Java sorted ??? (Big Theta!)
  12. String concatenating one line, it's not a problem
  13. BigInteger & BigDecimal are expensive. (avoid)
  14. Cache database connections. Object pooling. Apache common pool, Fast Object Pool, Vibur Object Pool
  15. Tune fetchSize when querying a big number of rows from DB. (default is 10, which makes it slow) 
  16. Mapper Objects: use MapStruct (fastest).
  17. log4j contention when writing to log file (async, buffer, network as a solution)
  18. exceptions are "expensive"
  19. Timeouts! (trigger'm!)
    Socket_timeouts TCP_NODELAY, SO_SNDBUF, SO_RCVBUF,  HTTP, JAX-WS, RestTemplate, JDBC timeouts :P
  20. Thread synchronized (as seen on log4j2), blocking java monitor 
  21. HTTP 1.1 instead 1.0 (keep-alive)
  22. Data source sizing
  23. PMD has several performance rules:  (among others)
    Don’t create instances of already existing BigInteger (BigInteger.ZERO, BigInteger.ONE)
    Avoid instantiating Boolean objects; you can reference Boolean.TRUE, Boolean.FALSE.
  24. Most of PMD, checkstyles rules are embedded at sonarqube.
  25. Jackson ObjectMapper must be reused (it's thread-safe). It is expensive.(use 2.8.7+ by race condition). Singleton, static or Object pooling (see above).
  26. CompletableFuture uses a forkjoin thread pool, which is a thread pool shared between all CompletableFutures and all parallel streams.
    https://dzone.com/articles/concurrency-in-action-using-javas-completable-futu
  27. https://github.com/devwebcl/async-springmvc-poc
  28. Java 8 parallel streams pitfall
    https://www.baeldung.com/java-8-parallel-streams-custom-threadpool https://medium.com/@michaelbespalov/parallel-stream-pitfalls-and-how-to-avoid-them-91f11808a16
  29. JVM CPU measure. It may be expensive for some JVM
  30. Every time you make something "static", consider if you want to make it "final" too. In most cases, you do. "static final"-s are much more optimize-able. https://t.co/Xm0YgDUTtL (from @shipilev) 
  31. Netty is a popular asynch framework, but it can suffer of OOM: io.netty.maxDirectMemory
  32. DO NOT use java 11 (~30% slower)

No comments :

Blog Archive

Disclaimer

The views expressed on this blog are my own and do not necessarily reflect the views of Oracle.