LinkedList 和 ArrayDeque的性能分析( 五 )

Now it is sufficient to call updateMap once in a while, when new log entries were received. They would be added to the correct map entry and map entries order wouldn\u0026#39;t be modified. All we need after that is a new processing logic.
private static void processFirstTimestamp( final Map\u0026lt;Integer, List\u0026lt;LogEvent\u0026gt;\u0026gt; eventMap ){ if ( eventMap.isEmpty() ) return; final Iterator\u0026lt;Map.Entry\u0026lt;Integer, List\u0026lt;LogEvent\u0026gt;\u0026gt;\u0026gt; iter = eventMap.entrySet().iterator(); Long firstTime = null; while ( iter.hasNext() ) { final Map.Entry\u0026lt;Integer, List\u0026lt;LogEvent\u0026gt;\u0026gt; entry = iter.next(); final List\u0026lt;LogEvent\u0026gt; lst = entry.getValue(); if ( firstTime == null ) firstTime = lst.get(0).time; else if ( lst.get(0).time != firstTime ) break; //extract entries for processing iter.remove(); processIp(lst); }} A small test method was implemented. It generates 100 entries for each of 1000 IP addresses for each of 50 timestamps. Each time we generate entries for slightly different set of IP addresses. First 5 timestamps are not processed (consider this as some buffering), after that we process one timestamp for each new portion of data (so we are always 5 timestamps late). Finally, all remaining timestamps are processed. Here is a test method for batch mode. Test method for initial approach just doesn\u0026#39;t use a map and calls processFirstTimestamp( LinkedList\u0026lt;LogEvent\u0026gt; ) instead.
private static void testEventsMap(){ final long start = System.currentTimeMillis(); final LinkedList\u0026lt;LogEvent\u0026gt; lst = new LinkedList\u0026lt;LogEvent\u0026gt;(); final Map\u0026lt;Integer, List\u0026lt;LogEvent\u0026gt;\u0026gt; map = new HashMap\u0026lt;Integer, List\u0026lt;LogEvent\u0026gt;\u0026gt;( 1000 ); int mlt = 0; for ( long t = 0; t \u0026lt; 50; ++t ) { for ( int ip = mlt * 100; ip \u0026lt; 1000 + mlt * 100; ++ip ) { for ( int num = 0; num \u0026lt; 100; ++num ) { final LogEvent event = new LogEvent( ip, t, "Event " + num ); lst.add( event ); } } mlt++; if ( mlt \u0026gt; 4 ) mlt = 0; updateMap( map, lst ); if ( t \u0026gt; 5 ) processFirstTimestamp( map ); } while ( !map.isEmpty() ) processFirstTimestamp( map ); System.out.println( "Total time batch = " + ( System.currentTimeMillis() - start ) );} Map based implementation completed 35 times faster than simple list based one - 10 seconds against 351 seconds. This is the price for multiple iterations over the full log event list.
See alsoJava collections overview - an overview of all standard JDK collections.
Summary 【LinkedList 和 ArrayDeque的性能分析】 If you need to optimize LinkedList performance in your code, try to stick to these rules:


推荐阅读