Di Jawa Apa Perbedaan Antara IdentityHashMap dan HashMap + Perbandingan Kinerja
Diterbitkan: 2021-10-19
Beberapa waktu yang lalu saya memiliki kasus khusus di mana saya harus membandingkan Map's Key berdasarkan equality operator (==)
. Operator kesetaraan (==) membandingkan referensi (alamat dalam memori) dari dua Kunci sebagai dua angka yang berbeda.
Di sisi lain, HashMap adalah komponen Java Collection Framework yang paling banyak digunakan yang membandingkan keunikan Kunci dengan bantuan metode equals()
.
Juga, IdentityHashMap
tidak menggunakan hash dari object.hashCode()
tetapi menggunakan System.identityHashCode(object)
. Kita bisa menggunakan IdentityHashMap untuk objek yang bisa berubah yang kode hashnya berubah selama runtime.
Jika Anda ingin mempelajari lebih lanjut tentang equals()
dan ==
yang berlaku on String Object
, ikuti tutorial ini: https://crunchify.com/how-to-override-equals-and-hashcode-method-in-java/.
Tes Dasar yang menunjukkan perilaku equals() dan == di atas:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
package crunchify . com . tutorials ; import java . util . HashMap ; import java . util . IdentityHashMap ; import java . util . Map ; /** * @author Crunchify.com * */ public class CrunchifyIdenityHashMapVsHashMapSample { public static void main ( String [ ] args ) { Map < String , String > crunchifyIdentityHashMap = new IdentityHashMap < String , String > ( ) ; Map < String , String > crunchifyHashMap = new HashMap < String , String > ( ) ; // Let's checkout what happens when we put Unique Key to IdentityHashMap crunchifyIdentityHashMap . put ( "Company" , "Crunchify" ) ; // this considered different object for == operator crunchifyIdentityHashMap . put ( new String ( "Company" ) , "Google" ) ; crunchifyIdentityHashMap . put ( "Company" , "Facebook" ) ; System . out . println ( "crunchifyIdentityHashMap KeySet Size: " + crunchifyIdentityHashMap . keySet ( ) . size ( ) ) ; // Let's checkout what happens when we put Unique Key to HashMap crunchifyHashMap . put ( "Company" , "Crunchify" ) ; // key1.equals(key2) returns true hence it removes the old value crunchifyHashMap . put ( new String ( "Company" ) , "Google" ) ; crunchifyHashMap . put ( "Company" , "Facebook" ) ; System . out . println ( "crunchifyHashMap KeySet Size: " + crunchifyHashMap . keySet ( ) . size ( ) ) ; } } |
Hasil:
1 2 |
crunchifyIdentityHashMap KeySet Size : 2 crunchifyHashMap KeySet Size : 1 |
Mari kita lakukan Performance Testing di kedua Maps:
- Buat Kelas Java:
CrunchifyIdentityHashMapVsHashMapPerformance
.java
-
startCrunchifyTest()
- Menghasilkan ukuran Peta Acak dalam jutaan
- Instansiasi dan Inisialisasi
crunchifyString[]
String Array objek dengan Angka Acak yang dihasilkan di atas dengan teks:This is Crunchify's Test # number
-
crunchifyCompareIdentityHashMapVsHashMap(String[] crunchifyString , Map<String, Integer> crunchifyMap , String name )
- Lewati semua parameter yang diperlukan ke metode ini
-
crunchifyMap
akan memiliki nilai IdentityHashMap / HashMap - Ulangi melalui crunchifyString[] dan masukkan nilai ke Peta — operasi ini membutuhkan waktu
- Ulangi melalui crunchifyString[] dan dapatkan nilai dari Peta — operasi ini membutuhkan waktu
- Kami akan mengetahui waktu eksekusi untuk kedua operasi di atas sehingga kami dapat membandingkan mana yang lebih baik untuk operasi di atas? IdentityHashMap ATAU HashMap
- Cetak hasil di atas
- Lakukan tugas di atas 2 dan 3 total 8 kali.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
package crunchify . com . tutorials ; import java . util . HashMap ; import java . util . IdentityHashMap ; import java . util . Map ; import java . util . Random ; /** * @author Crunchify.com * */ public class CrunchifyIdentityHashMapVsHashMapPerformance { static Random rand = new Random ( ) ; private static void startCrunchifyTest ( ) { // Let's run test for 5 times for ( int i = 0 ; i < 15 ; ++ i ) { // Let's create random Map size which we will use in IdentityHashMap and HashMap int randomMapSize = 1000000 + rand . nextInt ( 9000000 ) ; String [ ] crunchifyString = new String [ randomMapSize ] ; for ( int j = 0 ; j < randomMapSize ; ++ j ) // Assign below string to crunchifyString Object crunchifyString [ j ] = "This is Crunchify's Test #" + j ; System . out . println ( "\nIteration # " + i + " - Creating String with size: " + randomMapSize ) ; crunchifyCompareIdentityHashMapVsHashMap ( crunchifyString , new HashMap < String , Integer > ( randomMapSize ) , "HashMap" ) ; // Runs the garbage collector System . gc ( ) ; crunchifyCompareIdentityHashMapVsHashMap ( crunchifyString , new IdentityHashMap < String , Integer > ( randomMapSize ) , "IdentityHashMap" ) ; // Runs the garbage collector System . gc ( ) ; } } /** * @param crunchifyString * @param crunchifyMap * : IdentityHashMap / HashMap * @param name */ private static void crunchifyCompareIdentityHashMapVsHashMap ( String [ ] crunchifyString , Map < String , Integer > crunchifyMap , String name ) { long start = System . currentTimeMillis ( ) ; // put crunchifyString String[] to map for ( int put = 0 ; put < crunchifyString . length ; ++ put ) crunchifyMap . put ( crunchifyString [ put ] , put ) ; boolean result = false ; for ( int get = 0 ; get < crunchifyString . length ; ++ get ) { if ( crunchifyMap . get ( crunchifyString [ get ] ) ! = get ) result = true ; } System . out . println ( name + " time taken : \t" + ( System . currentTimeMillis ( ) - start ) / 1000. + " sec" ) ; // Check for result discrepancy if ( crunchifyMap . size ( ) ! = crunchifyString . length ) System . out . println ( "Please check size. Test failed" ) ; if ( result ) System . out . println ( "Result failed.." ) ; } public static void main ( String [ ] args ) { System . out . println ( "IdentityHashMap Vs. HashMap comparison Test started..." ) ; // method to compare IdentityHashMap and HashMap startCrunchifyTest ( ) ; } } |
Hasil:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
IdentityHashMap Vs . HashMap comparison Test started . . . Iteration # 0 - Creating String with size: 6964175 HashMap time taken : 3.155 sec IdentityHashMap time taken : 1.517 sec Iteration # 1 - Creating String with size: 6556459 HashMap time taken : 3.415 sec IdentityHashMap time taken : 1.466 sec < == IdentityHashMap gives better result for large object Iteration # 2 - Creating String with size: 9567664 HashMap time taken : 4.173 sec IdentityHashMap time taken : 2.339 sec < == better Iteration # 3 - Creating String with size: 4230755 HashMap time taken : 0.372 sec IdentityHashMap time taken : 0.911 sec Iteration # 4 - Creating String with size: 7821718 HashMap time taken : 1.096 sec IdentityHashMap time taken : 0.812 sec Iteration # 5 - Creating String with size: 8125421 HashMap time taken : 4.883 sec IdentityHashMap time taken : 1.876 sec < == better Iteration # 6 - Creating String with size: 3166432 HashMap time taken : 0.537 sec IdentityHashMap time taken : 0.708 sec Iteration # 7 - Creating String with size: 2821415 HashMap time taken : 0.227 sec IdentityHashMap time taken : 0.621 sec |
Pengamatan:
Seperti yang Anda lihat di sini sebagai hasilnya, untuk peta besar, IdentityHashMap berkinerja jauh lebih baik. Mengapa? IdentityHashMap doesn't use equals() and hashcode() methods
, yang dianggap sangat mahal.

Sekedar informasi:
Operasi di atas yang kami lakukan untuk menempatkan dan mendapatkan nilai dari dan ke dalam Peta sangat membutuhkan CPU.
