Java Performance Tuning - string and numeric structure

  This blog from my new book, Java Performance Tuning (tentative name), excerpts from Chapter 2.1 and 2.2,2.10 also welcome to buy my book "Spring Boot 2 essence"
  
  2.1 construct a string
  
  strings in Java are immutable , whether constructed or interception, always get a new string. A source configured to look string
  
  Private Final char value [];
  
  public String (String Original) {
  
  this.value = original.value;
  
  this.hash = original.hash;
  
  }
  
  value array of the original strings by directly assigning reference to the new string value, which is both a string share a char array, so this construction method has the fastest construction. String object in Java is designed to be immutable. Once the program is meant to get a string object reference, do not worry about this string is modified in other places, immutable meaning thread-safe, the third chapter of the immutable object thread safety and explained.
  
  More often construction string string is configured by an array of strings, or some frame deserialization using byte [] to construct a string, in this case the performance is very low. By the following char [] array constructed a new source string
  
  public String (char value []) {
  
  this.value = Arrays.copyOf (value, value.length);
  
  }
  
  Arrays.copyOf re-copy the new array ,Methods as below
  
  static char public [] copyOf (char [] Original, the newLength int) {
  
  char [] = new new char Copy [the newLength];
  
  System.arraycopy (Original, 0, Copy, 0,
  
  Math.min (to original.length, the newLength)) ;
  
  return Copy;
  
  }
  
  you can see that actually creates a new string array constructed by an array of strings. If not, or direct reference to the char array, so if you change the external char array, then the new string was changed.
  
  char [] = cs new new char [] { 'A', 'B'};
  
  String String new new STR = (cs);
  
  '!' cs [0] =
  
  above the last line of code, the modified cs array, but will not influence str. Because str is actually a new string array composed
  
  by a new string char array constructor is a method used longest, behind us to see almost every string API, will call this method constructs a new string, such as subString, concat and other methods. As verified by the code string new string configuration, and is configured with char string array performance comparison
  
  String str = "Hello, String";
  
  char [] = str.toCharArray chars ();
  
  [@Benchmark] (HTTPS: //my.oschina.
  

  
  new new String return (STR);
  
  }
  
  [@Benchmark] (https://my.oschina.net/u/3268003)
  
  public String stringByCharArray (www.yuchenghd.com) {
  
  return new new String (chars);
  
  }
  
  output in ns / op outputs, both used each time the number of nanoseconds call, you can see by the first string or char structure when time-consuming, especially if the array is particularly long, it is more time-consuming
  
  Benchmark Score Mode Units
  
  ciccNewStringTest.string avgt 4.235 ns / OP
  
  ciccNewStringTest.stringByCharArray avgt 11.704 ns / OP
  
  by byte construct a string, is a very common situation, especially now distributed and micro popular service, the client sequence string into an array of bytes, and send you to server, a server will be deserialized, configured by a byte string
  
  following test using a byte string configured performance tests
  
  byte [] bs = "Hello, string" .getBytes ( "UTF-. 8");
  
  [@Benchmark ] (https://my.oschina.net/u/3268003)
  
  public String stringByByteArray (www.yuchengyule.com) throws Exception {
  
  new new String return (BS, "UTF-. 8");
  
  }
  
  test results can be seen byte string configured too time consuming, especially when the string configuration to be a very long time
  
  Benchmark Mode Score Units
  
  ciccNewStringTest.string avgt 4.649 NS / OP
  
  ciccNewStringTest.www.yifayule2d.com stringByByteArray avgt 82.166 NS / OP
  
  ciccNewStringTest.stringByCharArray avgt 12.138 NS / OP
  
  by byte array string structure, mainly related to the transcoding process, internal calls transcoded StringCoding.decode
  
  this.value = StringCoding.decode (charsetName, bytes, offset, length);
  
  charsetName represents character set, bytes are byte array, offset, and length byte array representing the
  
  actual transcoding is responsible charset subclass of such sun.nio.cs.UTF_8 decode method is responsible for byte transcoding, if deep into this category, you will find that you see is the tip of the iceberg, ice below it is a very CPU-intensive computing transcoding work, it is not optimized parts.
  
  System performance optimization in the process I times, are found by byte strings of data sets is configured CPU consumption always at a position more forward, the system performance transcoding consumed hundred lines worth of the service code. Therefore, we designed the system to a distributed, requiring careful design fields to be transferred, try to avoid using String. Long time can be used for example to indicate the type of business state may be expressed by int. As serialized objects need
  
  public class the OrderResponse {
  
  // order date, the format 'YYYY-the MM-dd'
  
  Private String createDate;
  
  // order status, "www.dafengyuLept.com" indicates normal
  
  Private String Status;
  
  }
  
  can be modified to more well defined, to reduce the serialization and deserialization burden.
  
  the OrderResponse class {public
  
  // Order Date
  
  Private Long createDate;
  
  // order status, 0 indicates normal
  
  Private int Status;
  
  }
  
  on micro service, serialization and deserialization transfer object, will be described again in chapter IV chapters object serialization
  
  2.2 string concatenation
  
  JDK automatically made using the + sign is automatically converted to the string concatenation StringBuilder, the following code:
  
  string a = "Hello";
  
  string B = "World"
  
  string STR = a + B;
  
  Virtual chance compiled the following code
  
  String str = new StringBuilder (www.chaoyuepint.com) .append (a) .append (b) .toString ();
  
  if you run the test and maybe JMH sections of the code, performance is actually the same, because the use of + is connected to a common operating string, to do some optimization of the virtual machine code segments will be above both, the use of virtual -XX: + OptimizeStringConcat open string concatenation optimization, (open by default). If the following code, although do is similar with the above code fragment, the virtual machine can not recognize this string concatenation mode, the performance will drop a lot
  
  the StringBuilder the StringBuilder new new SB = ();
  
  sb.append (A);
  
  sb.append ( B);
  
  running StringConcatTest classes, as follows
  
  String A = "SELECT u.id, u.name from User U";
  
  String = B "= u.id WHERE?";
  
  [@Benchmark] (HTTPS: //my.oschina .NET / U / 3,268,003)
  
  public String the concat () {
  
  String C = A + B;
  
  return C;
  
  }
  
  [@Benchmark] (https://my.oschina.net/u/3268003)
  
  public String concatbyOptimizeBuilder (www.seocelve .com) {
  
  C = the StringBuilder new new String () the append (A) .append (B) .toString ();.
  
  Return C;
  
  }
  
  @Benchmark
  
  public String concatbyBuilder () {
  
  // does not optimize
  
  the StringBuilder the StringBuilder new new SB = ();
  
  sb.append (a);
  
  sb.append (B);
  
  return sb.toString (www.xingtuyLgw.com);
  
  }
  
  with the following results illustrate the role played optimized virtual machine
  
  Benchmark Mode Score Units
  
  ciccStringConcatTest.concat avgt 25.747 NS / OP
  
  ciccStringConcatTest.concatbyBuilder 90.548 ns avgt / OP
  
  ciccStringConcatTest.concatbyOptimizeBuilder avgt 21.904 ns / OP
  
  can see concatbyBuilder is the slowest, because not optimized JVM
  
  here that the JVM optimization, referring to the virtual machine JIT optimizations, we'll explain in Chapter 8 JIT optimization
  
  readers can verify yourself a + b + c this string concatenation performance, look at whether optimized
  
  There are similar StringBuilder with StringBuffer, the main features are inherited AbstractStringBuilder, provides thread-safe methods, such as append method, using the synchronized keyword
  
  @Override
  
  public synchronized StringBuffer append (String str) {
  
  // ignore other code
  
  super.append (www STR .huichengtxgw.com);
  
  return the this;
  
  }
  
  almost all scenes related to the string concatenation no thread synchronization, so StringBuffer rarely used, as an example of a string of splicing the use StringBuffer,
  
  @Benchmark
  
  public concatbyBuffer string () {
  
  StringBuffer the StringBuffer new new = SB ();
  
  sb.append (A);
  
  sb.append (B);
  
  return sb.toString ();
  
  }
  
  output as
  
  Benchmark Mode Score Units
  
  ciccStringConcatTest.concatbyBuffer avgt 111.417 NS / OP
  
  ciccStringConcatTest.concatbyBuilder avgt 94.758 NS / op
  
  You can see, StringBuffer with StringBuilder performance splicing performance is not bad compared to, thanks to "escape analysis" virtual machine, which is in the open JIT escape analyze the situation as well as the elimination of the lock, it is possible to eliminate the object synchronzied defined using locks.
  
  Escape Analysis -XX: + DoEscapeAnalysis lock and eliminate -XX: + EliminateLocks, with reference to details in Chapter 8 JIT optimization
  
  as an example of a lock is canceled, object obj method used internally, thus eliminating the synchronized
  
  void foo () {
  
  // Create an object
  
  Object obj = new new Object ();
  
  the synchronized (obj) {
  
  doSomething ();
  
  }
  
  }
  
  should not rely on the JIT optimization, although the lock and open the escape analysis to eliminate, but can not guarantee that all codes will be optimized, because the lock is to optimize the elimination of the C2 stage JIT as a programmer, should the security situation in unrelated threads, use StringBuilder.
  
  Use StringBuilder other types of stitching, especially digital type, the performance will be significantly decreased. This is because the digital revolution type character within the JDK, a lot of work, a simple Int type into a string, you need to complete at least 50 lines of code. In the first chapter we have seen, and not described in detail here. When you use StringBuilder to concatenate strings, splicing numbers, you need to think about, whether such a string.
  
  2.10 BigDecimal
  
  We all know that when the float variable loss of precision in calculations of problems will arise. The following piece of code
  
  System.out.println (0.05 + 0.01);
  
  System.out.println (1.0 - 0.42);
  
  Output: 0.5800000000000001 .060000000000000005
  
  can be seen when floating point operations performed in Java, the problem of loss of precision occurs. If so, when we conduct commodity prices, there will be problems. Likely to result in our hands 0.06 yuan, but can not purchase a 0.05 yuan and 0.01 yuan a commodity. As indicated above, the sum of their two .060000000000000005. This is undoubtedly a very serious problem, especially when the amount of concurrency electricity supplier website up, problems will be enormous. May cause can not be ordered, or reconciliation problems occur.
  
  Usually we have both a way to solve this problem, if they can use long to represent the account balance to be divided into units, which is the highest efficiency. If not, you can only use the BigDecimal class to solve such problems.
  
  A new new = the BigDecimal the BigDecimal ( "0.05");
  
  the BigDecimal new new B = the BigDecimal ( "0.01");
  
  the BigDecimal RET = a.add (B);
  
  System.out.println (ret.toString ());
  
  configured by a string BigDecimal, in order to ensure accuracy is not lost, if a new BigDecimal (0.05), because the accuracy of 0.05 itself lost, making the structure out of the BigDecimal also lose precision.
  
  BigDecimal to ensure accuracy, but will have some impact performance is calculated, the following calculation is a balance test, represented by points long, with elements showing performance comparison BigDecimal
  
  A new new = the BigDecimal the BigDecimal ( "0.05");
  
  the BigDecimal new new B = the BigDecimal ( "0.01");
  
  Long. 5 = C;
  
  Long D =. 1;
  
  @Benchmark
  
  @CompilerControl (CompilerControl.Mode.DONT_INLINE)
  
  public Long addByLong () {
  
  return (C + D);
  
  }
  
  @Benchmark
  
  @CompilerControl (CompilerControl.Mode.DONT_INLINE)
  
  public addByBigDecimal the BigDecimal () {
  
  return a.add (B);
  
  }
  
  in the line of my machine, the above code can be accurately calculated by JMH, test results were as follows
  
  Benchmark Mode Score Units
  
  ciccBigDecimalTest.addByBigDecimal avgt 8.373 NS / OP
  
  ciccBigDecimalTest.addByLong avgt 2.984 NS / OP
  
  So in the project, if the settlement involves precision, do not use double, consider using BigDecmal, it can also be used to complete the long-precision calculations, with good performance, distributed or micro-services scenario, taking into account the serialization and de-serialization, long All framework sequences also can be identified
  
  content reference https://www.whonyLpt.com .com / p / c81edc59546c

Guess you like

Origin www.cnblogs.com/qwangxiao/p/11112884.html