Java performance optimization Skills 2

Source: Internet
Author: User

Java performance optimization Skills 2
I have compiled a blog on java performance optimization. I am going to link java performance optimization 1.
1. Be cautious about Java loop traversal. List traversal in Java is much more troublesome than it looks. For example,:

  • private final List
       
         _bars;for(Bar bar : _bars) {    //Do important stuff}
       
  • B:
  • private final List
       
         _bars;for(int i = 0; i < _bars.size(); i++) {Bar bar = _bars.get(i);//Do important stuff}
       
  • Code A creates an iterator for this abstract list during execution, and code B directly uses get (I) to obtain elements, saving the iterator overhead compared with code.
  • In fact, there are still some trade-offs. Code A uses an iterator to ensure that the time complexity of getting elements is O (1) (using the getNext () and hasNext () methods ), the final time complexity is O (n ). For code B. the time complexity of get (I) is O (n) (assuming that this list is an aggregate list), the time complexity of the entire loop of code B is O (n ^ 2) (But if the list in code B is ArrayList, the time complexity of the get (I) method is O (1 ). Therefore, when deciding which Traversal method to use, we need to consider the underlying implementation of the List, the average length of the list and the memory used. If we need to optimize the memory, and the time complexity of ArrayList in most cases is O (1), we can select the method used by code B.
  •  
  • 2. Estimate the set size during initialization

    From this Java document, we can understand that "A HashMap instance has two factors that affect its performance: initial size and load factor ). When the size of the hash table reaches the product of the initial size and loading factor, the hash table performs rehash. If you want to store multiple mappings in a HashMap instance, you need to set a large enough initial size to store mappings more effectively, instead of making the hash table grow automatically and then rehash, this causes a performance bottleneck."


    We often encounter the need to traverse an ArrayList and save these elements to the HashMap. initializing the expected size of this HashMap can avoid overhead caused by re-hashing. The initialization size can be set to the size of the input array divided by the result value of the default loading Factor (here, 0.7 is used ):
    • Code before optimization:
    • HashMap
           
             _map;void addObjects(List
            
              input){  _map = new HashMap
             
              ();  for(Foo f: input)  {    _map.put(f.getId(), f);  }}
             
            
           

      Optimized Code
    • HashMap
           
             _map;void addObjects(List
            
              input){_map = new HashMap
             
              ((int)Math.ceil(input.size() / 0.7));for(Foo f: input){_map.put(f.getId(), f);}}
             
            
           
    •  
    • 3. latency expression Calculation

      In Java, all the method parameters will be calculated first (left to right) as long as there is a method parameter that is an expression before the method is called ). This rule causes unnecessary operations. Consider the following scenario: Use ComparisonChain to compare two Foo objects. One advantage of using such a comparison chain is that in the comparison process, the entire comparison ends if a compareTo method returns a non-zero value, avoiding many unnecessary comparisons. For example, in this scenario, the objects to be compared first consider their score, then the position, and finally the _ bar attribute:

       

      public class Foo {private float _score;private int _position;private Bar _bar; public int compareTo (Foo other) {return ComparisonChain.start().compare(_score, other.getScore()).compare(_position, other.getPosition()).compare(_bar.toString(), other.getBar().toString()).result;}}

       

      However, the above implementation will always convert two String objects to save the bar. toString () and other. getBar (). the value of toString (), even if the two strings are not required for comparison. To avoid such overhead, You can implement a comparator for the Bar object:

       

      public class Foo {private float _score;private int _position;private Bar _bar;private final BarComparator BAR_COMPARATOR = new BarComparator(); public int compareTo (Foo other) {return ComparisonChain.start().compare(_score, other.getScore()).compare(_position, other.getPosition()).compare(_bar, other.getBar(), BAR_COMPARATOR).result();}private static class BarComparator implements Comparator
           
             {@Overridepublic int compare(Bar a, Bar b) {return a.toString().compareTo(b.toString());}}}
           


       

      4. compile regular expressions in advance

      String operations are costly operations in Java. Fortunately, Java provides some tools to make regular expressions as efficient as possible. Dynamic regular expressions are rare in practice. In the following example, each call to String. replaceAll () contains a constant mode applied to the input value. Therefore, we can pre-compile this mode to save CPU and memory overhead.

      Before optimization:

      • private String transform(String term) {return outputTerm = term.replaceAll(_regex, _replacement);}
      •  
      • After optimization:
      • private final Pattern _pattern = Pattern.compile(_regex);private String transform(String term) {return outputTerm = _pattern.matcher(term).replaceAll(_replacement);}

        5. Cache it as much as possible if you can

        Saving results in the cache is also a way to avoid overhead. Multiple LRU (Least Recently Used) cache algorithms are available.


         

        6. The intern method of String is useful but dangerous.

        The intern feature of String can sometimes be used instead of cache.

        From this document, we can know:

        "A pool of strings, initially empty, is maintained privately by the class String. when the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals (Object) method, then the string from the pool is returned. otherwise, this String object is added to the pool and a reference to this String object is returned ".

        This feature is similar to caching, but there is a limit that you cannot set the maximum number of elements to accommodate. Therefore, if there is no limit on these intern strings (for example, strings represent some unique IDs), it will cause a rapid increase in memory usage.

         

         

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.