Program Code Optimization Essentials:
- String optimization: Parsing string source, understanding string common methods, using StringBuffer, StringBuilder.
- List, Map, set Optimization: Analysis commonly used ArrayList, LinkedList, HashMap, TreeMap, Linkedhashmap, set interface, set common method optimization.
- Using the nio:buffered, channel operation and principle, 0 copies are used.
- Reference optimizations: Strong references, weak references, soft references, virtual references, Weekhashmap.
- Optimization techniques: Common code optimization techniques. Not listed here, please refer to the following explanations.
String optimization:
StringBuffer and StringBuilder:
- The difference: StringBuffer is thread-safe, all methods of manipulating strings do synchronized operations, and StringBuilder is not thread-safe, so stringbuffer performance is less than StringBuilder.
- Note: Both StringBuffer and StringBuilder provide constructors with capacity parameters, the primary function is to specify the size of the initialization capacity (save string buffer), when the capacity exceeds capacity, will be expanded to twice times the original size , create a new memory space, copy the memory of the original space into the new memory space, and then free up the original memory space. Because memory copies are time-consuming, it's a good idea to specify the appropriate capacity.
- Compared with the + number of string: When using the + number splicing string, the compiler will replace the + number
new StringBuilder().append()
, improve the stitching efficiency, but in a large number of loops splicing, the compiler is not smart enough, each time the generation of new StringBuilder, generating a large number of GC, so performance is not high, It is best to use conact in loops or build your own StringBuffer or StringBuilder.
List interface: because the space is too long, so split, please refer to "Java Performance Optimization note-list interface analysis"//todo
Map Interface: Because the space is too long, so split, please refer to "Java Performance Optimization note-MAPT interface analysis"//todo
set interface: because the space is too long, so split, please refer to "Java Performance Optimization note-set interface analysis"//todo
Radnomaccess Interface: because the space is too long, so split, please refer to "Java Performance Optimization note-radnomaccess interface analysis"//todo
To optimize the collection operation:
- Duplicate code in the detach loop: The most common is the size () method of the call collection in the loop, and if the collection capacity is constant, be sure to get the size in advance,
int size=list.size();for(int i=0;i<size;i++){...}
although the size () method returns the internal variable size of the collection, but since size () is the method, there is a stack of functions , it takes time.
- Reduce method calls: As above, the method call exists on the stack, so it is best not to call the method in the Traversal collection.
- Omit the same operation: when iterating through a collection, we often get the objects in the collection through the Get method and then manipulate them, and if it is time-consuming to use the get in the loop, the get-out object is saved to the local variable, and then the local variables are manipulated. Repeated operations like this can be extracted.
- Using iterators: There are many ways to iterate through collections, such as for random access, foreach iterations, iterator iterations, and so on.
- For random access: The iterations are fairly fast on ArrayList, and the LinkedList based on the linked list is very poor for random access.
- Iterator iterations: The iterator accesses the collection at the fastest speed, each of which implements the Ietrator iterator interface, each of which optimizes access to the data based on the nature of the collection itself.
- foreach iteration: Because foreach is compiled into an iterator, it should normally be accessed faster, but there is an extra assignment to the iterator next () return variable after compilation, so the speed slows down.
Using NiO:
- NiO differs from traditional I/O:
- Buffer and channel:
- Buffer principle:
- Api:
- 0 Copies:
Reference type:
- Strong references: Objects that are directly new are strongly referenced, and strongly referenced GC collections are rare, and GC would rather throw a outofmemory exception if it is completely disconnected from GC root.
- Soft references: Soft references are collected by the GC when the heap approaches the threshold, so long as there is enough memory to keep the reference. Constructs a soft reference using Java.lang.SoftReference.
- Weak references: Soft references have the lowest reference level, as long as the GC thread is running, the existence of soft references will reclaim weak references, but the GC thread has a low priority, so it will survive for some time. Constructs a weak reference using Java.lang.WeekReference.
- Virtual Reference: A virtual reference cannot be directly referenced, and when a virtual reference is constructed using Java.lang.PhantomReference, the original strong reference is fetched with the Get () method, and Null is obtained directly because the virtual reference get () method implements NULL returned directly. The only purpose of a virtual reference is to recycle the resource with the reference queue, enter the reference queue when the GC recycles the strong reference, determine whether it is recycled in the reference queue by referencing the return value of the queue's remove () or poll () method, and clean up other resources if recycled.
- Weekhashmap:weakhashmap is a weakly quoted version of HashMap, where the elements of each key are weakly referenced. The Weakhashmap inheritance weekreference is used to put key in a weak reference, and also call the internal method expungestaleentries () directly or indirectly at get or put, which detects if the weak reference is recycled. If it is recycled, the resource of key is released.
- Reference queue: When an object changes its accessibility state, a reference to that object may be placed in the reference queue (reference. These queues are used by the garbage collector to communicate with our code about object accessibility changes. Java.lang.ReferenceQueue, passed in soft references, weak references, virtual reference constructors, and when GC threads are recycled, put objects in the reference queue, but they are not purged. Once the reference object is inserted into the queue by the garbage collector, the return value of its Get method will definitely be null, so the object can no longer be resurrected.
- Public Reference <? Extends under >poll (): Used to remove and return the next reference object in the queue, or null if the queue is empty.
- Public Referenceremove () throws Interruptedexception: Used to remove and return the next reference object in the queue, which blocks until the queue returns the available reference objects.
- Public Referenceremove (long timeout) throws Interrupte-dexception: Used to remove and return the next reference object in the queue. The method blocks until the queue returns a usable reference object, or ends after a specified timeout has been exceeded. Returns NULL if the specified timeout is exceeded. If the specified timeout is 0, it means that it will wait indefinitely.
Code Optimization Tips:
- Exception Optimizations: Never handle exceptions in loops, and looping through the exception stack can be time-consuming to put an exception trap out of the loop. The
- uses local variables: Local variables are stored in the local variable table of the virtual machine stack, and local variable tables are destroyed as the method is destroyed (out of the stack), so no GC is required. New objects are stored in the heap and require GC reclamation. Static variables are stored in the method area, generated by the Cinit construct at compile time, so the life cycle is the same as the class, and the method area GC is almost not recycled (permanent), so static is much more memory-intensive.
- bit operations: bit operation speed is the fastest, often used division can be replaced with >>, multiplication can be replaced by <<, shift right one equals to divide by 2, left one equals to multiply by 2.
- replacing switch:if and switch performance is not a big difference, but sometimes the use of if performance is higher, such as:
switch(num):case1:return1;case2:return2;case3:return3default:return -1
After using if optimization:
int swArr[3]={1,2,3};if(num<1||num>3){ return -1;}else{ return swArr[num];}
Because the random access to the array is very fast, using if is faster than switch. This needs to be optimized according to different business selectivity. In addition, the use of strategy or Factory mode can optimize the Swtich and if judgment, convenient decoupling.
- Expressions: Expression operations are time-consuming and can be extracted from repetitive expressions within loops without impacting the business into cyclic external variables to be saved, and then used inside the loop. In addition, we often use 24*60*60 such a way to calculate the number of seconds a day, in fact, you can directly write the calculation results in the variable.
- Expand Loop: Expand the loop to refer to the following code:
Before not expanded:
int num[]=newint[10000];for(int i=0;i<10000;i++){ num[i]=i;}
After expansion:
int num[]=newint[10000];for(int i=0;i<10000;i+=3){ num[i]=i; num[i+1]=i+1; num[i+2]=i+2;}
This occurs faster than the pre-deployment, because the loop reduces the step judgment.
- Using Boolean operations instead of bitwise operations: Bit operations are fast, there are bit logic, but when you use bitwise arithmetic with other logical operations in the judgment, Java's if will complete the execution of the bitwise operation before continuing to judge the other logical operations in the condition. The Boolean operation jumps directly to the IF block after the condition is satisfied, omitting the subsequent logical operation. But usually we only use Boolean arithmetic.
- Optimize array copy: Use System.arraycopy () because he is native, and it is very efficient to invoke a copy of the operating system implementation.
- Using buffers: Bufferedinput and bufferedoutput have been described in the previous article, and the same bufferedwrtier and bufferedreader efficiency is also very high. The buffer is used preferentially.
- Using static methods: Static methods can be used directly without building an instance, and because the method area GC is rarely recycled, and the JVM caches commonly used classes, some common tool classes are more likely to encapsulate static performance. And it is more expressive than function overloading.
- Use design mode: You can replace the new operation with a prototype mode when the object is larger, especially if the object constructor is time consuming, you can use the prototype schema clone object directly, or you can use the Clone method in Beanutil under Apache Commons. Also in some businesses, you can use the singleton mode, the enjoy meta-mode, proxy mode, Factory mode and other common design patterns to optimize the object generation process, improve performance.
Java Performance Tuning Note (iii) Java program optimization