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)