Analysis of jvm execution state
Code tuning
Regular expressions need precompiling
Q
In the process of using, the wrong way is used: regenerate the Pattern every time
Pattern pattern = Pattern.compile(datePattern1); Matcher match = pattern.matcher(sDate);
Causes system threads to run for a long time in
S
Pattern should be defined as static final static variable to avoid multiple precompiles
private static final Pattern pattern = Pattern.compile(regexRule); private void func(...) { Matcher m = pattern.matcher(content); if (m.matches()) { ... }
All ArrayList & LinkedList remove (object o) are traversed
Q
ArrayList: public boolean remove(Object o) { if (o == null) { for (int index = 0; index < size; index++) if (elementData[index] == null) { fastRemove(index); return true; } } else { for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); return true; } } return false; } LinkedList: public boolean remove(Object o) { if (o == null) { for (Node<E> x = first; x != null; x = x.next) { if (x.item == null) { unlink(x); return true; } } } else { for (Node<E> x = first; x != null; x = x.next) { if (o.equals(x.item)) { unlink(x); return true; } } } return false; }
Discovery: both of them traverse the entire List when removing the specified object.
By comparing the source code: the underlying implementation of ArrayList is an array; LinkedList is a two-way linked list (internal Node to encapsulate external data Object)
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
- When searching by random index: the performance of direct array operation of ArrayList is better. LinkedList needs to traverse the bidirectional linked list to locate the Node under index.
- When post adding, ArrayList may need to be expanded (System.arraycopy). LinkedList points the next pointer of the original Node directly to the new object.
- When specifying index to add, ArrayList needs to perform System.arraycopy operation. In the worst case of LinkedList, you need to traverse to get the Node on the specified index to do the pointer redirection (in the best case, directly at the end of the queue, by determining index = size).
- When deleting, ArrayList needs to do the System.arraycopy operation. Whether the LinkedList is deleted by the specified index or by the specified object, it needs to traverse the bidirectional linked list again to find the specified Node. But the performance should still be faster than ArrayList.
In conclusion, LinkedList performance is better than ArrayList when modified. But it is not enough to support the current test requirements of large amount of data.
S
Choose to use HashSet!
The bottom implementation of hashSet is to implement hashCode hash positioning through HashMap (the bottom layer of HashMap is also an array, and there are nodes inside to encapsulate external data objects).
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
V value;
Node<K,V> next;
public boolean add(E e) { return map.put(e, PRESENT)==null; } public boolean remove(Object o) { return map.remove(o)==PRESENT; }
When hashMap is modified, it will first locate the specific storage location on the array table through hash.
public V put(K key, V value) { return putVal(hash(key), key, value, false, true); } public V remove(Object key) { Node<K,V> e; return (e = removeNode(hash(key), key, null, false, true)) == null ? null : e.value; } static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }