JIN XU created EMAIL-193: ---------------------------- Summary: use ConcurrentHashMap insteadof WeakHashMap Key: EMAIL-193 URL: https://issues.apache.org/jira/browse/EMAIL-193 Project: Commons Email Issue Type: Improvement Environment: win10, jdk8 Reporter: JIN XU
Hi. throughtout my performance test (using Jprofiler), I found out WeakHashMap is far slower than ConcurrentHashMap. Should we use ConcurrentHashMap instead of WeakHashMap? I will attach my test codes here. {code:java} /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */import org.apache.commons.beanutils2.WeakFastHashMap;import java.util.Objects; import java.util.Random; import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap;public class WeakFastHashMapTest { static final TreeSet<Integer> treeSet = new TreeSet<>(); static final Random random = new Random(); static final WeakFastHashMap<Integer, Integer> weakFastHashMap = new WeakFastHashMap<>(); static final ConcurrentHashMap<Integer, Integer> concurrentHashMap = new ConcurrentHashMap<>(); static final int INIT_SIZE = 50000; static final double WRITE_CHANCE = 0.01; static final double READ_NON_EXIST_CHANCE = 0.30; public static void main(String[] args) { for (int i = 0; i < INIT_SIZE; i++) { writeRandom(); } System.out.println("init over"); weakFastHashMap.setFast(true); for (int i = 0; ; i++) { if (i % 100000 == 0) { System.out.println("running> i : " + i + " size: " + treeSet.size()); } double ifWrite = random.nextDouble(); if (ifWrite < WRITE_CHANCE) { writeRandom(); } else { double ifNonExist = random.nextDouble(); if (ifNonExist < READ_NON_EXIST_CHANCE) { readNonExist(); } else { readExist(); } } } } public static void writeRandom() { Integer nowKey = random.nextInt() * random.nextInt(); Integer nowValue = random.nextInt() * random.nextInt(); treeSet.add(nowKey); weakFastHashMap.put(nowKey, nowValue); concurrentHashMap.put(nowKey, nowValue); } public static void readExist() { Integer nowKey = null; while (nowKey == null) { nowKey = treeSet.lower(random.nextInt() * random.nextInt()); } read(nowKey); } public static void readNonExist() { Integer nowKey = random.nextInt() * random.nextInt(); while (treeSet.contains(nowKey)) { nowKey = random.nextInt() * random.nextInt(); } read(nowKey); } public static void read(Integer nowKey) { Integer value1 = weakFastHashMap.get(nowKey); Integer value2 = concurrentHashMap.get(nowKey); if (!Objects.equals(value1, value2)) { System.out.println("not equal! nowKey : " + nowKey + " value1 : " + value1 + " value2 : " + value2); } } } {code} and, Jprofiler Call Tree: h2. Call Tree |*Session:*|WeakFastHashMapTest| |*Time of export:*|Sunday, May 31, 2020 2:56:14 PM CST| |*JVM time:*|12:23| | | | |*View mode:* |Tree| |*Thread selection:* |<img "height="16" width="16" border="0" hspace="0" vspace="0" src=" jprofiler_images/selector_group_16.png"> All thread groups| |*Thread status:* |<img "height="6" width="16" border="0" hspace="0" vspace="0" src=" jprofiler_images/ff00c400_bff000000.png"> Runnable| |*Aggregation level:* |Methods| ---- |!jprofiler_images/tree/menu_tee_minus_18.gif|width=18,height=18,align=left!!jprofiler_images/call_method_16_filter_underlay_16.png|width=16,height=16,align=left! !jprofiler_images/pixel_ff990000.png|width=49,height=7,vspace=2!!jprofiler_images/pixel_ffff3300.png|width=1,height=7,vspace=2! 100.0% - 743 s - 1 inv. WeakFastHashMapTest.main| |!jprofiler_images/tree/menu_bar_18.gif|width=18,height=18,align=left!!jprofiler_images/tree/menu_tee_minus_18.gif|width=18,height=18,align=left!!jprofiler_images/call_method_16.png|width=16,height=16,align=left! !jprofiler_images/pixel_ff990000.png|width=48,height=7,vspace=2!!jprofiler_images/pixel_ffff3300.png|height=7,vspace=2! 96.6% - 718 s - 157,464 inv. org.apache.commons.beanutils2.WeakFastHashMap.put| |!jprofiler_images/tree/menu_bar_18.gif|width=18,height=18,align=left!!jprofiler_images/tree/menu_bar_18.gif|width=18,height=18,align=left!!jprofiler_images/tree/menu_tee_minus_18.gif|width=18,height=18,align=left!!jprofiler_images/call_method_16.png|width=16,height=16,align=left! !jprofiler_images/pixel_ff990000.png|width=48,height=7,vspace=2!!jprofiler_images/pixel_ffff3300.png|height=7,vspace=2! 96.6% - 718 s - 107,464 inv. org.apache.commons.beanutils2.WeakFastHashMap.cloneMap| |!jprofiler_images/tree/menu_bar_18.gif|width=18,height=18,align=left!!jprofiler_images/tree/menu_bar_18.gif|width=18,height=18,align=left!!jprofiler_images/tree/menu_bar_18.gif|width=18,height=18,align=left!!jprofiler_images/tree/menu_corner_minus_18.gif|width=18,height=18,align=left!!jprofiler_images/call_method_16.png|width=16,height=16,align=left! !jprofiler_images/pixel_ff990000.png|width=48,height=7,vspace=2!!jprofiler_images/pixel_ffff3300.png|height=7,vspace=2! 96.6% - 718 s - 107,464 inv. org.apache.commons.beanutils2.WeakFastHashMap.createMap| |!jprofiler_images/tree/menu_bar_18.gif|width=18,height=18,align=left!!jprofiler_images/tree/menu_bar_18.gif|width=18,height=18,align=left!!jprofiler_images/tree/menu_bar_18.gif|width=18,height=18,align=left!!jprofiler_images/tree/pixel_transparent_1.gif|width=18,height=18,align=left!!jprofiler_images/tree/menu_corner_18.gif|width=18,height=18,align=left!!jprofiler_images/call_method_16_filter_underlay_16.png|width=16,height=16,align=left! !jprofiler_images/pixel_ffff3300.png|width=48,height=7,vspace=2! 96.6% - 718 s - 107,464 inv. java.util.WeakHashMap.<init>| |!jprofiler_images/tree/menu_bar_18.gif|width=18,height=18,align=left!!jprofiler_images/tree/menu_bar_18.gif|width=18,height=18,align=left!!jprofiler_images/tree/menu_corner_18.gif|width=18,height=18,align=left!!jprofiler_images/call_method_16_filter_underlay_16.png|width=16,height=16,align=left! !jprofiler_images/pixel_ffff3300.png|height=7,vspace=2! 0.0% - 80,342 µs - 157,463 inv. java.util.Map.put| |!jprofiler_images/tree/menu_bar_18.gif|width=18,height=18,align=left!!jprofiler_images/tree/menu_tee_minus_18.gif|width=18,height=18,align=left!!jprofiler_images/call_method_16.png|width=16,height=16,align=left! !jprofiler_images/pixel_ffff3300.png|height=7,vspace=2! 0.5% - 3,625 ms - 10,654,869 inv. org.apache.commons.beanutils2.WeakFastHashMap.get| |!jprofiler_images/tree/menu_bar_18.gif|width=18,height=18,align=left!!jprofiler_images/tree/menu_bar_18.gif|width=18,height=18,align=left!!jprofiler_images/tree/menu_corner_18.gif|width=18,height=18,align=left!!jprofiler_images/call_method_16_filter_underlay_16.png|width=16,height=16,align=left! !jprofiler_images/pixel_ffff3300.png|height=7,vspace=2! 0.3% - 2,263 ms - 10,654,869 inv. java.util.Map.get| |!jprofiler_images/tree/menu_bar_18.gif|width=18,height=18,align=left!!jprofiler_images/tree/menu_corner_18.gif|width=18,height=18,align=left!!jprofiler_images/call_method_16.png|width=16,height=16,align=left! !jprofiler_images/pixel_ffff3300.png|height=7,vspace=2! 0.0% - 1 µs - 1 inv. org.apache.commons.beanutils2.WeakFastHashMap.setFast| |!jprofiler_images/tree/menu_corner_minus_18.gif|width=18,height=18,align=left!!jprofiler_images/call_method_16_filter_underlay_16.png|width=16,height=16,align=left! !jprofiler_images/pixel_ffff3300.png|height=7,vspace=2! 0.0% - 2,776 µs - 1 inv. WeakFastHashMapTest.<clinit>| |!jprofiler_images/tree/pixel_transparent_1.gif|width=18,height=18,align=left!!jprofiler_images/tree/menu_corner_minus_18.gif|width=18,height=18,align=left!!jprofiler_images/call_method_16.png|width=16,height=16,align=left! !jprofiler_images/pixel_ffff3300.png|height=7,vspace=2! 0.0% - 51 µs - 1 inv. org.apache.commons.beanutils2.WeakFastHashMap.<init>| |!jprofiler_images/tree/pixel_transparent_1.gif|width=18,height=18,align=left!!jprofiler_images/tree/pixel_transparent_1.gif|width=18,height=18,align=left!!jprofiler_images/tree/menu_tee_minus_18.gif|width=18,height=18,align=left!!jprofiler_images/call_method_16.png|width=16,height=16,align=left! !jprofiler_images/pixel_ffff3300.png|height=7,vspace=2! 0.0% - 36 µs - 1 inv. org.apache.commons.beanutils2.WeakFastHashMap.createMap| |!jprofiler_images/tree/pixel_transparent_1.gif|width=18,height=18,align=left!!jprofiler_images/tree/pixel_transparent_1.gif|width=18,height=18,align=left!!jprofiler_images/tree/menu_bar_18.gif|width=18,height=18,align=left!!jprofiler_images/tree/menu_corner_18.gif|width=18,height=18,align=left!!jprofiler_images/call_method_16_filter_underlay_16.png|width=16,height=16,align=left! !jprofiler_images/pixel_ffff3300.png|height=7,vspace=2! 0.0% - 7 µs - 1 inv. java.util.WeakHashMap.<init>| |!jprofiler_images/tree/pixel_transparent_1.gif|width=18,height=18,align=left!!jprofiler_images/tree/pixel_transparent_1.gif|width=18,height=18,align=left!!jprofiler_images/tree/menu_corner_18.gif|width=18,height=18,align=left!!jprofiler_images/call_method_16_filter_underlay_16.png|width=16,height=16,align=left! !jprofiler_images/pixel_ffff3300.png|height=7,vspace=2! 0.0% - 3 µs - 1 inv. java.util.HashMap.<init>| 96.6% of the total running time is at WeakHashMap.put And notice that only 1/100 chance we write, other 99/100 chance we read. If you want the data about 1/1000 or other, I will be happy to run/provide. -- This message was sent by Atlassian Jira (v8.3.4#803005)