ãã ãã32ãããã®ãããã¹ãããã®å ŽåïŒ
以äžã§ã¯ãã©ã®ããã«æž¬å®ãè¡ããããã説æããåçããã®ããã«èŠããçç±ãç解ããŠã¿ãŸãã
ææãšæ¹æ³
枬å®ã¯ãéåžžã®Javaé åã ãã§ãªããjava.utilããã³java.util.concurrentããã®æšæºJavaã³ã¬ã¯ã·ã§ã³ã«å¯ŸããŠãè¡ãããŸããã IdentityHashSetããã³ConcurrentHashSetã³ã¬ã¯ã·ã§ã³ã¯ãCollections.newSetFromMapïŒïŒã¡ãœããã䜿çšããŠã察å¿ãããããããäœæãããŸãã ãã¹ãŠã®ã³ã¬ã¯ã·ã§ã³ã¯ãæåã«èŠçŽ ã®æ°ãæå®ããã«ããã©ã«ãã§åæåããïŒå¿ èŠãªé åãé€ãïŒããã®åŸãaddã¡ãœããã䜿çšããŠãã¹ããªããžã§ã¯ãã§æºããããŸããïŒãããŠãé åã«å¯ŸããŠå²ãåœãŠãå®è¡ãããŸããïŒã 1ãã10,000ãŸã§ã®ç°ãªãæ°ã®èŠçŽ ã䜿çšããŠãåã¿ã€ãã®çŽ500ã®ã³ã¬ã¯ã·ã§ã³ãäœæãããŸãããèŠçŽ ãšããŠãã©ã³ãã ãªæåã§æ§æãããã©ã³ãã ãªé·ãã®10,000ã®ç°ãªãæååã䜿çšãããŸããã ååãšããŠãèŠçŽ èªäœã¯ConcurrentHashSetã«ã®ã¿åœ±é¿ãããããã§ã圱é¿ãäžãããããã°ã©ãã¯ã©ã®ããŒã¿ã§ãåãããã«èŠããŸãã
é åãåããåŸãã¡ã¢ãªãã³ããããã»ã¹ããååŸãããEclipse Memory Analyzerã䜿çšããŠåæãããŸãããããã«ããããªããžã§ã¯ãèªäœã¯å«ãŸããããªãŒããŒãããã®ã¿ãå«ãŸããåã³ã¬ã¯ã·ã§ã³ã®ä¿æã»ãããéåžžã«æ£ç¢ºã«èšç®ãããŸããã ããšãã°ã次ã®ããã«ãªããŸãã
ããã§ã¯ãExcelã«ã³ããŒããç°¡åãªæ°åŠæŒç®ãšãã°ã©ãã£ã«ã«ãšãã£ã¿ãŒã§å°ãè¿œå ã®å³é¢ã䜿çšããŠããããããŸãã
çµæã®è°è«
åã³ã¬ã¯ã·ã§ã³ã¯ããªãŒããŒãããã³ã¹ãã®å¢çãäœããèŠçŽ ãå€ãã»ã©ãã³ã¬ã¯ã·ã§ã³ã«è¿ãããšãå€ãããšãããããŸãã ãã ããäžéšã®ã³ã¬ã¯ã·ã§ã³ã§ã¯ããªãŒããŒãããé¢æ°ãæ°åŠçãªæå³ã§ãã®å¢çã«åæãããšã¯èšããŸããã ããšãã°ãArrayListã¯8ãã€ãïŒ64ãããã®å ŽåïŒã«ãªã£ãŠããŸãããæ°ããã¡ã¢ãªãå²ãåœãŠããããã³ã«12ãã€ãã«ãžã£ã³ããç¶ããŸãã
èå³æ·±ãããšã«ã32ããããš64ãããã®ã°ã©ãã¯éåžžã«äŒŒãŠããŸããã»ãšãã©ã®ã³ã¬ã¯ã·ã§ã³ã§ã¯ãConcurrentSkipListSetãšLinkedListã®2ã€ã®äŸå€ãé€ããŠãã°ã©ããååç°ãªããŸãã åã³ã¬ã¯ã·ã§ã³ãåå¥ã«æ€èšãããã®ãããªã¹ã±ãžã¥ãŒã«ã§ããçç±ã確èªããŠãã ããã
é å
æãåçŽãªãªãã·ã§ã³ã¯ãèŠçŽ ã®æ°ãäºåã«ããã£ãŠããé åã§ãã ãã®äžã«ãåãªããžã§ã¯ããžã®åç §ãæ ŒçŽãããŸãïŒ4ïŒ8ïŒãã€ãïŒæ¬åŒ§å ã®å€ã¯64ãããJVMã®å ŽåïŒãããã«ãé åã®é·ãã¯intã4ãã€ãã§ããªããžã§ã¯ãèšè¿°åã¯8ïŒ16ïŒãã€ãã§ãã ããã«ãåãªããžã§ã¯ãã¯8ãã€ãã§ã¢ã©ã€ã³ãããããã32ãããããšã«å¶æ°åã®èŠçŽ ãæã€é åã¯4ãã€ãã倱ããŸãã çµæïŒãªããžã§ã¯ãããšã«4ïŒ8ïŒãã€ããš12ã24ãã€ãã®å®æ°ã
空ã®é åã¯16ïŒ24ïŒãã€ããå æããŸãã
é åãªã¹ã
ããã§ã¯ããããã«éãã¯ãããŸãããã»ãšãã©åãã§ããé åå ã®èŠçŽ ã®æ°ãäºåã«ããããªããããé åã«ã¯ããŒãžã³ïŒããã©ã«ãã§ã¯10èŠçŽ ïŒãå²ãåœãŠãããå¿ èŠã«å¿ããŠ1.5å以äžæ¡åŒµãããŸãã
int newCapacity = (oldCapacity * 3)/2 + 1;
ãããã£ãŠãã°ã©ãã¯6ïŒ12ïŒãã€ãã«ãžã£ã³ãããŸãã å®æ°ããããã«å€§ãããªããŸãã40ïŒ64ïŒãã€ããé åã«å ããŠãé åãžã®åç §ããªã¹ãã®å®éã®ãµã€ãºãããã³å€æŽã®æ°ïŒConcurrentModificationExceptionãã¹ããŒããïŒãæ ŒçŽããArrayListãªããžã§ã¯ãããããŸãã ããã§ããããã¯ãã©ãã ãã®ããŒã¿ããããäºåã«ããããªãå Žåãåãã¿ã€ãã®ããŒã¿ãä¿åããæãçµæžçãªæ¹æ³ã§ãã
èŠçŽ ãæããªãããã©ã«ãã®æ§ç¯ãããArrayListã¯80ïŒ144ïŒãã€ããåããŸãã
LinkedList
ãªã³ã¯ãªã¹ãã®å Žåãç»åã¯é åã®ãããªãã®ã§ããåæ²ç·ã®æŒžè¿ç·ã«ãªããã¡ã§ãã java.util.LinkedList.Entryã¿ã€ãã®1ã€ã®ãµãŒãã¹ãªããžã§ã¯ãããªã¹ãã¢ã€ãã ããšã«äœæãããŸãã ãããã®åãªããžã§ã¯ãã«ã¯3ã€ã®ãªã³ã¯ïŒãªã¹ãé ç®èªäœãåããã³æ¬¡ã®ãšã³ããªãžïŒãå«ãŸãã32ãããã§ã®ã¢ã©ã€ã¡ã³ãã«ãã4ãã€ãã倱ããããããæçµçã«åãšã³ããªã«ã¯24ïŒ40ïŒãã€ããå¿ èŠã§ãã å®æ°ã«ã¯ãLinkedListãªããžã§ã¯ãã®ãã³ãã«ãå é ã®ãšã³ããªãšãã®ãªã³ã¯ããªã¹ãã®ãµã€ãºãããã³å€æŽã®æ°ã48ïŒ80ïŒãã€ãå«ãŸããŸãã ãã¡ãããããã§ã¯ã¡ã¢ãªãå²ãåœãŠãããªãããã空ã®ãªã¹ãã¯åãéãå æããŸãã
ããªãŒã»ãã
äžè¬ã«ã䜿çšããããã¹ãŠã®ã»ããã¯ãããã«åºã¥ããŠããŸãã å Žåã«ãã£ãŠã¯ãåå¥ã®å®è£ ã¯å€å°ã³ã³ãã¯ãã«ãªãå¯èœæ§ããããŸãããäžè¬çãªã³ãŒãã¯ãã¡ããéèŠã§ãã
ã°ã©ãã¯ãLinkedListãšé åã®ããã«ãèŠããŸãã åèŠçŽ ã«å¯ŸããŠãããŒãå€ã芪ãå·Šããã³å³ã®åã®5ã€ã®ãªã³ã¯ãå«ãjava.util.TreeMap.EntryããªãŒãã©ã³ããäœæãããŸãã ãããã«å ããŠãæã®è²ãèµ€ãŸãã¯é»ã瀺ãããŒã«å€æ°ãä¿åãããŸãïŒ èµ€é»æšãåç §ïŒã åäžã®ããŒã«å€æ°ã¯4ãã€ãã䜿çšãããããã¬ã³ãŒãå šäœã¯32ïŒ64ïŒãã€ãã䜿çšããŸãã
TreeMapã®å®æ°ããŒã¿ã¯ãã³ã³ãã¬ãŒã¿ãžã®åç §ãããªãŒã®ã«ãŒããžã®åç §ïŒLinkedListã®å€©äœãšã³ããªãšã¯ç°ãªããã«ãŒãã¯æå³ãããç®çã«äœ¿çšãããŸã-ã»ããã®å®éã®èŠçŽ ãåç §ïŒãentrySetãžã®ãªã³ã¯ãnavigableKeySetãdescendingMapïŒãããã®ãªããžã§ã¯ãã¯ãªã³ããã³ãã§äœæãããŸãïŒãå€æŽã®ãµã€ãºãšæ°ã TreeMapãªããžã§ã¯ãèšè¿°åã䜿çšãããšã48ïŒ80ïŒãã€ããååŸãããŸãã TreeSetèªäœã¯ãèšè¿°åãšTreeMapãžã®ãªã³ã¯ã®ã¿ãè¿œå ããŸãã åèšã§64ïŒ104ïŒãã€ããåºåãããŸãã 空ã®ã»ããã®ééã¯åãã§ãã ãšããã§ãã¡ã¢ãªæ¶è²»ã¯ããªãŒã®ãã©ã³ã¹ã®çšåºŠã«äŸåããŸããã
ããã·ã¥ã»ãã
HashSetã¯HashMapã«åºã¥ããŠããŸãããããã¯TreeMapããå°ãè€éã§ãã åèŠçŽ ã«å¯ŸããŠãããŒãžã®ãªã³ã¯ãEntryã«ç¶ãå€ïŒè€æ°ã®ãšã³ããªãããã·ã¥ããŒãã«ã®åãã»ã«ã«å ¥ãå ŽåïŒãããã³ããã·ã¥å€èªäœãå«ãjava.util.HashMap.Entryãšã³ããªãäœæãããŸãã å šäœã§ããšã³ããªã®ééã¯24ïŒ48ïŒãã€ãã§ãã
ãšã³ããªã«å ããŠããšã³ããªãžã®ãªã³ã¯ãå«ãããã·ã¥ããŒãã«ããããŸãããã®ããŒãã«ã«ã¯ãæåã¯16åã®èŠçŽ ãå«ãŸããèŠçŽ æ°ããµã€ãºã®75ïŒ ãè¶ ãããšåã«ãªããŸãïŒ75ïŒ ã¯ããã©ã«ãã®loadFactorå€ã§ãã³ã³ã¹ãã©ã¯ã¿ã§æå®ã§ããŸãïŒã ã€ãŸããããã©ã«ãã§æ§ç¯ããå ŽåãèŠçŽ ã®æ°ã12ã24ã48ã96ãªã©ãè¶ ãããšããŒãã«ãæ¡å€§ãããŸãïŒ2 n * 3ãã°ã©ãã®æåŸã®ããŒã¹ãã¯6144èŠçŽ ã§ãïŒã å¢å çŽåŸã®ããŒãã«ã¯ãèŠçŽ æ°ã®2 / 0.75 = 2.67åã§ããã€ãŸããç·æ¶è²»éã¯èŠçŽ ãããçŽ34.67ïŒ69.33ïŒãã€ãã§ãïŒå®æ°ã¯ã«ãŠã³ãããŸããïŒã å¢å ã®çŽåã§ã¯ãããŒãã«ã¯èŠçŽ æ°ã®1 / 0.75 = 1.33åã§ãããåèšæ¶è²»éã¯èŠçŽ ããã29.33ïŒ58.67ïŒãã€ãã§ãã ã¡ã¢ãªäœ¿çšéã¯ãããã·ã¥è¡çªãçºçããé »åºŠãšã¯å®å šã«ç¬ç«ããŠããããšã«æ³šæããŠãã ããã
åžæãã人ã¯å®æ°ã³ã³ããŒãã³ããèªåã§èšç®ã§ããŸããããã©ã«ãã§åæåããã空ã®HashSetã®éãã¯136ïŒ240ïŒãã€ãã ãšèšããŸãã
LinkedHashSet
HashSetãšã»ãŒåãã§ãã java.util.LinkedHashMap.Entryã䜿çšããŠjava.util.HashMap.Entryãç¶æ¿ããåãšæ¬¡ã®èŠçŽ ã«2ã€ã®ãªã³ã¯ãè¿œå ãããããã°ã©ãã¯HashSetãã8ïŒ16ïŒãã€ãé«ããããŒãã«æ¡åŒµ37.33ïŒ74.67ïŒã®åã«éããŸã以é-èšé²42.67ïŒ85.33ïŒã LinkedListã®ããã«ãã»ããã®èŠçŽ ãåç §ããªãå é ã®ãšã³ããªãæ ŒçŽããããããå®æ°ãå¢å ããŸããã æ°ããäœæãããLinkedHashSetã®ééã¯176ïŒ320ïŒãã€ãã§ãã
IdentityHashSetïŒnewSetFromMapçµç±ïŒ
IdentityHashMapã¯éåžžã«èå³æ·±ããã®ã§ãã ããŒãçããã§ã¯ãªã==ãšæ¯èŒããSystem.identityHashCodeã䜿çšããããšã«ãããæšæºã®ãããã³ã³ãã©ã¯ãã«éåããŸãã ãŸããEntryã®ãããªãªããžã§ã¯ããäœæããããã¹ãŠã®ããŒãšå€ã1ã€ã®é åïŒå¶æ°èŠçŽ ã®ããŒãå¥æ°èŠçŽ ã®å€ïŒã«åçŽã«æ ŒçŽãããããèå³æ·±ããã®ã§ãã è¡çªãçºçããå Žåããªã¹ãã¯äœæãããŸãããããªããžã§ã¯ãã¯é åã«æ²¿ã£ãæåã®ç©ºãã»ã«ã«æžã蟌ãŸããŸãã ããã«ããããã¹ãŠã®ã»ããã§èšé²çãªäœããªãŒããŒãããã³ã¹ããéæãããŸãã
IdentityHashMapã¯ã2/3ãè¶ ãããã³ã«é åã®ãµã€ãºã2åã«ããŸãïŒHashMapãšã¯ç°ãªãããã®ä¿æ°ã¯æ§æã§ããŸããïŒã ããã©ã«ãã§ã¯ã32åã®èŠçŽ ãæã€é åãäœæãããŸãïŒã€ãŸããé åã®ãµã€ãºã¯64ã§ãïŒã ãããã£ãŠã21ã42ã85ã170ãªã©ãè¶ ãããšæ¡åŒµãçºçããŸãïŒ[2 n / 3]ãã°ã©ãã®æåŸã®ãµãŒãžã¯5461ã§ãïŒã æ¡åŒµåã®é åã«ã¯ãIdentityHashMapã®ããŒã®3åãæ¡åŒµåŸã®6åã®èŠçŽ ãå«ãŸããŠããŸãã ãããã£ãŠããªãŒããŒãããã¯èŠçŽ ããšã«12ïŒ24ïŒã24ïŒ48ïŒãã€ãã§ãã ããã©ã«ãã§ã¯ã空ã®ã»ããã¯ããªãå€ã-344ïŒ656ïŒãã€ãããããŸããããã§ã«9ã€ã®èŠçŽ ããããããä»ã®ãã¹ãŠã®ã»ãããããçµæžçã«ãªããŸãã
ConcurrentHashSetïŒnewSetFromMapçµç±ïŒ
ConcurrentHashMapã¯ããã£ãŒããèŠçŽ èªäœïŒãŸãã¯ããã·ã¥é¢æ°ïŒã«äŸåããæåã®ã³ã¬ã¯ã·ã§ã³ã§ãã 倧ãŸãã«èšããšãããã¯åºå®æ°ã®ã»ã°ã¡ã³ãïŒããã©ã«ãã§ã¯16ïŒã®ã»ããã§ãããåã»ã°ã¡ã³ãã¯HashMapã®åæã¢ããã°ã§ãã å€æŽãããããã·ã¥ã³ãŒãããã®ãããã®äžéšã¯ãã»ã°ã¡ã³ãã®éžæã«äœ¿çšãããç°ãªãã»ã°ã¡ã³ããžã®ã¢ã¯ã»ã¹ã¯äžŠè¡ããŠçºçããå¯èœæ§ããããŸãã java.util.concurrent.ConcurrentHashMap.HashEntryã¯java.util.HashMap.Entryãšã»ãšãã©åãã§ãããããå¶éã§ã¯ããªãŒããŒãããã¯HashMapèªäœã®ãªãŒããŒããããšåãã§ãã ã°ã©ããåæã«äžæããªããããã»ã°ã¡ã³ãã®ãµã€ãºã®å¢å ã¯ç¬ç«ããŠçºçããŸãããŸããããå€ãã®èŠçŽ ãããã»ã°ã¡ã³ããå¢å ããŸãã
ãã®ã³ã¬ã¯ã·ã§ã³ã¯ã16åã®ã»ã°ã¡ã³ããããã«éå§ãããããããã16åã®ã¬ã³ãŒããšããã€ãã®è£å©ãã£ãŒã«ããæã€ããŒãã«ãæã£ãŠãããããåæãµã€ãº-1304ïŒ2328ïŒãã€ãã®é¢ã§ãããã«ãªããŸããã ãã ãã10,000åã®èŠçŽ ã®å ŽåãConcurrentHashSetã¯HashSetããã0.3ïŒ ã ã倧ãããªããŸãã
ConcurrentSkipListSet
ConcurrentSkipListMapãä»ããŠå®è£ ãããç§ã®æèŠã§ã¯ãèšè¿°ãããã³ã¬ã¯ã·ã§ã³ã®äžã§æãè€éã§ãã ã¢ã«ãŽãªãºã ã®ã¢ã€ãã¢ã¯Habréã§èª¬æãããŠãããããããã§ã¯è©³ãã説æããŸããã ããã§åŸãããã¡ã¢ãªãµã€ãºã¯ããŒã¿ã«äŸåããŸããããåéã¯æ¬äŒŒä¹±æ°ãžã§ãã¬ãŒã¿ã«ãã£ãŠéå§ããããããé決å®çã§ãã 次ã®æ¬äŒŒä¹±æ°ã«åºã¥ããŠãã€ã³ããã¯ã¹ãšã³ããªãè¿œå ãããã©ãããšãã¬ãã«æ°ã決å®ããŸãã 1ã€ã®java.util.concurrent.ConcurrentSkipListMap.Nodeãªããžã§ã¯ãã¯ãããŒãå€ãããã³æ¬¡ã®ããŒããžã®åç §ãå«ãåèŠçŽ ã«å¯ŸããŠå¿ ãäœæãããåçŽã«æ¥ç¶ããããªã¹ãã圢æããŸãã ããã«ãããèŠçŽ ããšã«24ïŒ40ïŒãã€ããåŸãããŸãã ããã«ã2ã€ã®èŠçŽ ããšã«çŽ1ã€ã®ã€ã³ããã¯ã¹ãšã³ããªïŒjava.util.concurrent.ConcurrentSkipListMap.IndexïŒãäœæãããŸãïŒæåã®ã¬ãã«ã§ã¯ã4çªç®ããšã«ã¬ã³ãŒããããã2çªç®ã«ã¯8çªç®ããšã«ããªã©ïŒã åã€ã³ããã¯ã¹ãšã³ããªã®éãã¯Nodeãšåãã§ããïŒããã«ã¯3ã€ã®ãªã³ã¯ããããŸãïŒãåèšã§åèŠçŽ ã«ã¯çŽ36ïŒ60ïŒãã€ããå¿ èŠã§ãã åã¬ãã«ïŒHeadIndexïŒã«ã¯ãããã¬ã³ãŒãããããŸããããããã¯ã»ãšãã©ãªãïŒã»ãŒèŠçŽ æ°ã®å¯Ÿæ°ïŒã®ã§ãç¡èŠã§ããŸãã
空ã®ConcurrentSkipListSetã«ã¯ã1ã€ã®HeadIndexãš1ã€ã®ç©ºã®ããŒããäœæãããŸãã ããã©ã«ãã§æ§ç¯åŸãã³ã¬ã¯ã·ã§ã³ã¯112ïŒ200ïŒãã€ãããããŸãã
ãªãã§ãããªããšïŒ
çµæã¯ã»ãšãã©äºæãããç§ã®çŽæçãªã¢ã€ãã¢ãšççŸããŠããŸããã ãã®ããã競åããã³ã¬ã¯ã·ã§ã³ã¯éåžžã®ã³ã¬ã¯ã·ã§ã³ãããã¯ããã«å€ããLinkedHashSetã¯TreeSetãšHashSetã®éã®ã©ããã«é 眮ããå¿ èŠããããšèããŸããã ãŸããã¡ã¢ãªæ¶è²»ããªããžã§ã¯ãèªäœã«äŸåããªãããšã¯äºå®äžãªãããšãé©ãã¹ãããšã§ãããããªãŒã®ãã©ã³ã¹ã®åºŠåããããã·ã¥ããŒãã«å ã®è¡çªã®æ°ã¯äœã«ã圱é¿ããã競åããªãã³ã¬ã¯ã·ã§ã³ã®å ŽåããªãŒããŒãããã®ãµã€ãºãæ倧1ãã€ãã®ç²ŸåºŠã§äºåã«æ±ºå®ã§ããŸãã ããŸããŸãªã³ã¬ã¯ã·ã§ã³ã®å éšæ§é ãæãäžããããšã¯èå³æ·±ãããšã§ããã ãã®ç 究ã«å ·äœçãªå®éçãªå©ç¹ã¯ãããŸããïŒããããŸããã誰ããèªåã§æ±ºããŠãã ããã