LinkedList 和 ArrayDeque的性能分析( 四 )
For such kind of data, LinkedList is a good solution - we can remove elements from any position of the list quite cheap. First of all we need a method to extract events for particular IP address from the network log. Do not try to select elements and remove them from the list afterwards, even if you already have one of these methods in your library, because it would require 2 iterations instead of one for extraction. We have to use ListIterator in the extraction method because this is the only way to iterate elements and remove some of them from the source list at the same time.private static final class LogEvent{ public final int ipv4; public final long time; public final String eventDesc; private LogEvent( final int ipv4, final long time, final String eventDesc ) { this.ipv4 = ipv4; this.time = time; this.eventDesc = eventDesc; }} private static List\u0026lt;LogEvent\u0026gt; extractForIp( final LinkedList\u0026lt;LogEvent\u0026gt; fullLst, final int ip ){ final List\u0026lt;LogEvent\u0026gt; res = new ArrayList\u0026lt;LogEvent\u0026gt;( 10 ); final ListIterator\u0026lt;LogEvent\u0026gt; iter = fullLst.listIterator(); while ( iter.hasNext() ) { final LogEvent event = iter.next(); if ( event.ipv4 == ip ) { res.add( event ); iter.remove(); } } return res;} Now we are able to process all IP addresses in the current timestamp.private static void processIp( final List\u0026lt;LogEvent\u0026gt; lst ){ //...processing logic here} private static void processFirstTimestamp( final LinkedList\u0026lt;LogEvent\u0026gt; fullList ){ if ( fullList.isEmpty() ) return; final long firstTime = fullList.getFirst().time; while ( !fullList.isEmpty() \u0026amp;\u0026amp; fullList.getFirst().time == firstTime ) { final int ip = fullList.getFirst().ipv4; final List\u0026lt;LogEvent\u0026gt; eventsForIp = extractForIp( fullList, ip ); processIp( eventsForIp ); }} Unfortunately, this algorithm will perform poorly when you have a lot of messages/IP addresses in your log. Each time you have to scan all events but you will end up with only a few messages after extraction. The better way is to maintain a map from IP addresses to lists of their events. Both extraction and appending would work much faster in this case. We will use LinkedHashMapin order to keep original order of found IP. If we have removed all entries for some IP address and added some new entries for the same IP address later, this IP address would be added to the tail of iteration order. updateMap method adds all entries from the input list to the map and cleans input list. We need only this method for both initial and subsequent calls.private static Map\u0026lt;Integer, List\u0026lt;LogEvent\u0026gt;\u0026gt; extractMap( final List\u0026lt;LogEvent\u0026gt; fullLst ){ final Map\u0026lt;Integer, List\u0026lt;LogEvent\u0026gt;\u0026gt; res = new LinkedHashMap\u0026lt;Integer, List\u0026lt;LogEvent\u0026gt;\u0026gt;( 10 ); updateMap( res, fullLst ); return res;} private static void updateMap( final Map\u0026lt;Integer, List\u0026lt;LogEvent\u0026gt;\u0026gt; eventMap, final List\u0026lt;LogEvent\u0026gt; fullLst ){ for ( final LogEvent event : fullLst ) { List\u0026lt;LogEvent\u0026gt; lst = eventMap.get( event.ipv4 ); if ( lst == null ) { lst = new ArrayList\u0026lt;LogEvent\u0026gt;( 10 ); eventMap.put( event.ipv4, lst ); } lst.add( event ); } fullLst.clear();}
推荐阅读
- 球叔教你买车|丰田也玩起了三缸机,性能堪比2.0T,这款小钢炮比GTI还狠
- 有车club|高性能运动化取向 宝马128ti海外售价公布 约合27.61万元起
- 趣头条|捷豹F-PACE SVR官图发布 造型细节调整/动力性能进一步提升
- 汽车|性能媲美SUV 柴油皮卡首推长城皮卡风骏7
- 澎湃汽车圈|试驾名爵MG领航 运动性和实用性能否兼顾?
- 环球车讯网|空间更实用,号称史上最强性能,纯电版福特F-150渲染图
- 扉旅汽车|中国量产车性能大赛,柯迪亚克GT表现“狠”不错?
- 想买个30w—50w的轿车,外形优雅精致,气质沉静内敛。要能够顾家,稳定,安全性能好。请帮忙推荐一下
- 谈车工坊|在“中国之最”赛道挑战双擎混动的性能极限
- 水泥灰雷凌|水泥灰丰田雷凌到店实拍,1.8L动力,远比思域更性能!
