{"id":379174,"date":"2024-06-19T09:00:27","date_gmt":"2024-06-19T09:00:27","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=379174"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=379174","title":{"rendered":"<span>\u0423\u0441\u043a\u043e\u0440\u044f\u0435\u043c sync.Map \u043d\u0430 73% \u0437\u0430 40 \u0441\u0442\u0440\u043e\u043a \u043a\u043e\u0434\u0430<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 &#8212; \u044d\u0442\u043e \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u0441\u043f\u043e\u0440\u0442\u0438\u0432\u043d\u044b\u0439 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442, \u043d\u0430\u043a\u0438\u0434\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0434 \u0432\u0435\u0447\u0435\u0440 \u043d\u0430 \u043a\u043e\u043b\u0435\u043d\u043a\u0435 \u0441 \u0446\u0435\u043b\u044c\u044e \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>\u0417\u0430\u0434\u0430\u0447\u0430 \u0431\u044b\u043b\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0430\u043d\u0430\u043b\u043e\u0433 sync.Map \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u043d\u044b\u0439 \u043f\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043a \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u0443, \u0441\u043f\u043e\u0440\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0430 \u0440\u0430\u0434\u0438.<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u0440\u0430\u0437\u0443 \u043a \u043a\u043e\u0434\u0443 \u0438 \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0430\u043c:<\/p>\n<pre><code class=\"go\">package main  import ( \"hash\/fnv\" \"sync\" )  type bucket struct { data sync.Map }  type FastSyncMap struct { buckets []*bucket }  func NewSyncMap(bucketCount int) *FastSyncMap { buckets := make([]*bucket, bucketCount) for i := range buckets { buckets[i] = &amp;bucket{} } return &amp;FastSyncMap{buckets: buckets} }  func (m *FastSyncMap) hash(key string) int { h := fnv.New32a() h.Write([]byte(key)) return int(h.Sum32()) % len(m.buckets) }  func (m *FastSyncMap) Store(key string, value interface{}) { index := m.hash(key) b := m.buckets[index] b.data.Store(key, value) }  func (m *FastSyncMap) Load(key string) (value interface{}, ok bool) { index := m.hash(key) b := m.buckets[index] return b.data.Load(key) }<\/code><\/pre>\n<p>\u0412\u043e\u0442 \u0442\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a:<\/p>\n<pre><code class=\"go\">package main  import ( \"strconv\" \"sync\" \"testing\" )  var data = map[string]int{ \"key-001\": 437, \"key-002\": 384, \"key-003\": 983, \"key-004\": 543, \"key-005\": 276, \"key-006\": 128, \"key-007\": 753, \"key-008\": 832, \"key-009\": 621, \"key-010\": 519, \"key-011\": 407, \"key-012\": 905, \"key-013\": 132, \"key-014\": 658, \"key-015\": 294, \"key-016\": 745, \"key-017\": 389, \"key-018\": 910, \"key-019\": 482, \"key-020\": 371, \"key-021\": 648, \"key-022\": 573, \"key-023\": 781, \"key-024\": 452, \"key-025\": 390, \"key-026\": 167, \"key-027\": 296, \"key-028\": 854, \"key-029\": 731, \"key-030\": 513, \"key-031\": 249, \"key-032\": 675, \"key-033\": 890, \"key-034\": 412, \"key-035\": 567, \"key-036\": 712, \"key-037\": 361, \"key-038\": 284, \"key-039\": 946, \"key-040\": 709, \"key-041\": 541, \"key-042\": 673, \"key-043\": 325, \"key-044\": 498, \"key-045\": 823, \"key-046\": 654, \"key-047\": 832, \"key-048\": 276, \"key-049\": 792, \"key-050\": 619, \"key-051\": 485, \"key-052\": 527, \"key-053\": 831, \"key-054\": 491, \"key-055\": 350, \"key-056\": 764, \"key-057\": 539, \"key-058\": 204, \"key-059\": 926, \"key-060\": 687, \"key-061\": 498, \"key-062\": 143, \"key-063\": 359, \"key-064\": 871, \"key-065\": 604, \"key-066\": 318, \"key-067\": 425, \"key-068\": 691, \"key-069\": 536, \"key-070\": 174, \"key-071\": 523, \"key-072\": 680, \"key-073\": 352, \"key-074\": 870, \"key-075\": 429, \"key-076\": 237, \"key-077\": 491, \"key-078\": 391, \"key-079\": 702, \"key-080\": 826, \"key-081\": 318, \"key-082\": 563, \"key-083\": 496, \"key-084\": 791, \"key-085\": 142, \"key-086\": 380, \"key-087\": 943, \"key-088\": 467, \"key-089\": 389, \"key-090\": 905, \"key-091\": 281, \"key-092\": 478, \"key-093\": 654, \"key-094\": 193, \"key-095\": 849, \"key-096\": 740, \"key-097\": 268, \"key-098\": 431, \"key-099\": 739, \"key-100\": 511, \"key-101\": 234, \"key-102\": 593, \"key-103\": 800, \"key-104\": 137, \"key-105\": 405, \"key-106\": 872, \"key-107\": 364, \"key-108\": 230, \"key-109\": 793, \"key-110\": 649, \"key-111\": 507, \"key-112\": 391, \"key-113\": 170, \"key-114\": 923, \"key-115\": 478, \"key-116\": 375, \"key-117\": 682, \"key-118\": 195, \"key-119\": 735, \"key-120\": 341, \"key-121\": 263, \"key-122\": 498, \"key-123\": 149, \"key-124\": 517, \"key-125\": 350, \"key-126\": 630, \"key-127\": 809, \"key-128\": 472, \"key-129\": 367, \"key-130\": 953, \"key-131\": 284, \"key-132\": 576, \"key-133\": 395, \"key-134\": 719, \"key-135\": 364, \"key-136\": 157, \"key-137\": 861, \"key-138\": 495, \"key-139\": 267, \"key-140\": 436, \"key-141\": 513, \"key-142\": 722, \"key-143\": 184, \"key-144\": 637, \"key-145\": 912, \"key-146\": 501, \"key-147\": 294, \"key-148\": 178, \"key-149\": 843, \"key-150\": 671, }  func BenchmarkMySyncMap(b *testing.B) { m := NewSyncMap(len(data)) b.ResetTimer()  for i := 0; i &lt; b.N; i++ { for k, v := range data { m.Store(k, v) }  for k, v := range data { v2, ok := m.Load(k) if !ok || v2 != v { b.Fatalf(\"key %s not found in cache (%v) or incorrect value: %v\", k, ok, v2) } } } }  func BenchmarkGoSyncMap(b *testing.B) { var m sync.Map b.ResetTimer()  for i := 0; i &lt; b.N; i++ { for k, v := range data { m.Store(k, v) }  for k, v := range data { v2, ok := m.Load(k) if !ok || v2 != v { b.Fatalf(\"key %s not found in cache (%v) or incorrect value: %v\", k, ok, v2) } } } }  func BenchmarkMySyncMapParallel(b *testing.B) { m := NewSyncMap(150 * 2) b.ResetTimer()  b.RunParallel(func(pb *testing.PB) { for pb.Next() { for k, v := range data { m.Store(k, v) }  for k, v := range data { v2, ok := m.Load(k) if !ok || v2 != v { b.Fatalf(\"key %s not found in cache (%v) or incorrect value: %v\", k, ok, v2) } } } }) }  func BenchmarkGoSyncMapParallel(b *testing.B) { var m sync.Map b.ResetTimer() b.RunParallel(func(pb *testing.PB) { for pb.Next() { for k, v := range data { m.Store(k, v) }  for k, v := range data { v2, ok := m.Load(k) if !ok || v2 != v { b.Fatalf(\"key %s not found in cache (%v) or incorrect value: %v\", k, ok, v2) } } } }) }  func BenchmarkFastSyncMapWriteMillion(b *testing.B) { m := NewSyncMap(150 * 2) totalEntries := 1000000 b.ResetTimer()  b.RunParallel(func(pb *testing.PB) { for pb.Next() { for i := 0; i &lt; totalEntries; i++ { key := strconv.Itoa(i) m.Store(key, i) m.Load(key) } } }) }  func BenchmarkSyncMapWriteMillion(b *testing.B) { var m sync.Map totalEntries := 1000000 b.ResetTimer()  b.RunParallel(func(pb *testing.PB) { for pb.Next() { for i := 0; i &lt; totalEntries; i++ { key := strconv.Itoa(i) m.Store(key, i) m.Load(key) } } }) }<\/code><\/pre>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0430 \u043d\u0430 \u043c\u043e\u0435\u043c \u041f\u041a<\/p>\n<pre><code class=\"go\">goos: linux goarch: amd64 pkg: lesson cpu: 12th Gen Intel(R) Core(TM) i7-12700K BenchmarkMySyncMap BenchmarkMySyncMap-20                      74986        15030 ns\/op BenchmarkGoSyncMap BenchmarkGoSyncMap-20                      76708        15605 ns\/op BenchmarkMySyncMapParallel BenchmarkMySyncMapParallel-20             479565         2518 ns\/op BenchmarkGoSyncMapParallel BenchmarkGoSyncMapParallel-20             455433         2679 ns\/op BenchmarkFastSyncMapWriteMillion BenchmarkFastSyncMapWriteMillion-20            4    264691361 ns\/op BenchmarkSyncMapWriteMillion BenchmarkSyncMapWriteMillion-20                3    458739675 ns\/op PASS<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0437\u0430\u043f\u0438\u0441\u0438\\\u0447\u0442\u0435\u043d\u0438\u0438 \u0432 \u043e\u0434\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430\u044f sync.Map \u0432\u044b\u0438\u0433\u0440\u044b\u0432\u0430\u0435\u0442.<br \/>\u041f\u0440\u0438 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u0441 \u043c\u0430\u043b\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439 fast sync map \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u043d\u0430 2%.<br \/>\u041f\u0440\u0438 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u0441 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439 \u0432 \u043c\u0438\u043b\u043b\u0438\u043e\u043d \u0437\u0430\u043f\u0438\u0441\u0435\u0439 fast sync map \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u043d\u0430 73%.<\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u0435 \u043c\u043e\u0435\u0439 \u0442\u0430\u0447\u043a\u0438, \u0433\u0434\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u043b\u0441\u044f \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a:<\/p>\n<pre><code class=\"bash\">$ lscpu Architecture:            x86_64   CPU op-mode(s):        32-bit, 64-bit   Address sizes:         46 bits physical, 48 bits virtual   Byte Order:            Little Endian CPU(s):                  20   On-line CPU(s) list:   0-19 Vendor ID:               GenuineIntel   Model name:            12th Gen Intel(R) Core(TM) i7-12700K     CPU family:          6     Model:               151     Thread(s) per core:  2     Core(s) per socket:  12     Socket(s):           1     Stepping:            2     CPU max MHz:         5000,0000     CPU min MHz:         800,0000     BogoMIPS:            7219.20     Flags:               fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bt                          s rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm sse4_1 sse4_2 x2apic movbe popcnt                           tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx                          2 smep bmi2 erms invpcid rdseed adx smap clflushopt clwb intel_pt sha_ni xsaveopt xsavec xgetbv1 xsaves split_lock_detect avx_vnni dtherm ida arat pln pts hwp hwp_notify hwp_act_window h                          wp_epp hwp_pkg_req hfi vnmi umip pku ospke waitpkg gfni vaes vpclmulqdq tme rdpid movdiri movdir64b fsrm md_clear serialize pconfig arch_lbr ibt flush_l1d arch_capabilities Virtualization features:    Virtualization:        VT-x Caches (sum of all):        L1d:                   512 KiB (12 instances)   L1i:                   512 KiB (12 instances)   L2:                    12 MiB (9 instances)   L3:                    25 MiB (1 instance) NUMA:                       NUMA node(s):          1   NUMA node0 CPU(s):     0-19 Vulnerabilities:            Gather data sampling:  Not affected   Itlb multihit:         Not affected   L1tf:                  Not affected   Mds:                   Not affected   Meltdown:              Not affected   Mmio stale data:       Not affected   Retbleed:              Not affected   Spec rstack overflow:  Not affected   Spec store bypass:     Mitigation; Speculative Store Bypass disabled via prctl   Spectre v1:            Mitigation; usercopy\/swapgs barriers and __user pointer sanitization   Spectre v2:            Mitigation; Enhanced \/ Automatic IBRS; IBPB conditional; RSB filling; PBRSB-eIBRS SW sequence; BHI BHI_DIS_S   Srbds:                 Not affected   Tsx async abort:       Not affected<\/code><\/pre>\n<pre><code class=\"bash\">sudo lshw -short -C memory H\/W path           Device     Class          Description ======================================================== \/0\/0                          memory         64KiB BIOS \/0\/3b                         memory         40GiB System Memory \/0\/3b\/0                       memory         8GiB DIMM Synchronous 4800 MHz (0,2 ns) \/0\/3b\/1                       memory         16GiB DIMM Synchronous 4800 MHz (0,2 ns) \/0\/3b\/2                       memory         16GiB DIMM Synchronous 4800 MHz (0,2 ns) \/0\/3b\/3                       memory         [empty] \/0\/4b                         memory         384KiB L1 cache \/0\/4c                         memory         256KiB L1 cache \/0\/4d                         memory         10MiB L2 cache \/0\/4e                         memory         25MiB L3 cache \/0\/4f                         memory         128KiB L1 cache \/0\/50                         memory         256KiB L1 cache \/0\/51                         memory         2MiB L2 cache \/0\/52                         memory         25MiB L3 cache \/0\/100\/14.2                   memory         RAM memory<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0437\u0430\u0433\u043b\u044f\u043d\u0435\u043c \u0432 pprof memory profile, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<pre><code>sync.Map  Showing nodes accounting for 67752.28kB, 99.89% of 67827.20kB total       flat  flat%   sum%        cum   cum% 51064.96kB 75.29% 75.29% 54407.03kB 80.21%  sync.(*Map).Swap  6975.31kB 10.28% 85.57% 67752.34kB 99.89%  lesson.BenchmarkSyncMapWriteMillion.func1  6373.84kB  9.40% 94.97%  6373.84kB  9.40%  strconv.formatBits  3338.13kB  4.92% 99.89%  3338.13kB  4.92%  sync.newEntry (inline)  ====================================  Showing nodes accounting for 108636.43kB, 99.92% of 108720.77kB total       flat  flat%   sum%        cum   cum% 45864.58kB 42.19% 42.19% 75216.60kB 69.18%  sync.(*Map).Swap 23786.82kB 21.88% 64.06% 23786.82kB 21.88%  sync.(*Map).dirtyLocked 22013.31kB 20.25% 84.31% 22013.31kB 20.25%  strconv.formatBits 11164.25kB 10.27% 94.58% 86380.85kB 79.45%  lesson.(*FastSyncMap).Store  5561.55kB  5.12% 99.70%  5561.55kB  5.12%  sync.newEntry (inline)<\/code><\/pre>\n<p><code>FastSyncMap<\/code> \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u044f\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0432 1.6 \u0440\u0430\u0437\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u0430\u043c\u044f\u0442\u0438, \u0447\u0435\u043c <code>sync.Map<\/code>.<\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u043d\u0430\u0448\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u043b\u0443\u0447\u0448\u0443\u044e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0437\u0430 \u0441\u0447\u0435\u0442 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u043f\u0430\u043c\u044f\u0442\u0438. \u042d\u0442\u043e \u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0438\u0441\u0441 \u043c\u0435\u0436\u0434\u0443 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043f\u0430\u043c\u044f\u0442\u0438, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0438\u0435\u043c\u043b\u0435\u043c\u043e \u0432 \u0441\u043b\u0443\u0447\u0430\u044f\u0445, \u043a\u043e\u0433\u0434\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0432\u044b\u0441\u043e\u043a\u0430\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/046\/20f\/c5a\/04620fc5a36a2e5e3c7110e86b87063e.png\" alt=\"\u0414\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0430\u043c\u044f\u0442\u0438 sync.Map\" title=\"\u0414\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0430\u043c\u044f\u0442\u0438 sync.Map\" width=\"1210\" height=\"823\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/046\/20f\/c5a\/04620fc5a36a2e5e3c7110e86b87063e.png\"\/><\/p>\n<div><figcaption>\u0414\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0430\u043c\u044f\u0442\u0438 sync.Map<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f78\/cdc\/568\/f78cdc568b3243494f6e1fe34befd8d4.png\" alt=\"\u0414\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0430\u043c\u044f\u0442\u0438 Fast Sync Map\" title=\"\u0414\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0430\u043c\u044f\u0442\u0438 Fast Sync Map\" width=\"1018\" height=\"869\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f78\/cdc\/568\/f78cdc568b3243494f6e1fe34befd8d4.png\"\/><\/p>\n<div><figcaption>\u0414\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0430\u043c\u044f\u0442\u0438 Fast Sync Map<\/figcaption><\/div>\n<\/figure>\n<p>\u0418\u0434\u0435\u043c \u0434\u0430\u043b\u044c\u0448\u0435 &#8212; \u0441\u043c\u043e\u0442\u0440\u0438\u043c CPU \u043f\u0440\u043e\u0444\u0438\u043b\u044c<\/p>\n<pre><code>go tool pprof fastsyncmap_cpu.prof File: lesson.test Type: cpu Time: Jun 19, 2024 at 10:38am (MSK) Duration: 1s, Total samples = 3.10s (309.30%) Entering interactive mode (type \"help\" for commands, \"o\" for options) (pprof) top Showing nodes accounting for 2130ms, 68.71% of 3100ms total Dropped 52 nodes (cum &lt;= 15.50ms) Showing top 10 nodes out of 80       flat  flat%   sum%        cum   cum%      440ms 14.19% 14.19%      560ms 18.06%  runtime.mapaccess2      300ms  9.68% 23.87%      300ms  9.68%  runtime.(*mspan).base (inline)      270ms  8.71% 32.58%      270ms  8.71%  runtime.(*gcBits).bitp (inline)      270ms  8.71% 41.29%      310ms 10.00%  runtime.findObject      210ms  6.77% 48.06%      210ms  6.77%  aeshashbody      190ms  6.13% 54.19%      190ms  6.13%  runtime.procyield      160ms  5.16% 59.35%     1380ms 44.52%  runtime.gcDrain      160ms  5.16% 64.52%     1190ms 38.39%  runtime.scanobject       70ms  2.26% 66.77%       70ms  2.26%  sync.(*entry).tryExpungeLocked       60ms  1.94% 68.71%       60ms  1.94%  runtime.(*mspan).heapBitsSmallForAddr               go tool pprof syncmap_cpu.profcpu.prof File: lesson.test Type: cpu Time: Jun 19, 2024 at 10:38am (MSK) Duration: 1.01s, Total samples = 2.13s (210.73%) Entering interactive mode (type \"help\" for commands, \"o\" for options) (pprof) top Showing nodes accounting for 1550ms, 72.77% of 2130ms total Dropped 47 nodes (cum &lt;= 10.65ms) Showing top 10 nodes out of 56       flat  flat%   sum%        cum   cum%      280ms 13.15% 13.15%      380ms 17.84%  runtime.mapaccess2      270ms 12.68% 25.82%      270ms 12.68%  runtime.procyield      210ms  9.86% 35.68%      210ms  9.86%  runtime.(*mspan).base (inline)      190ms  8.92% 44.60%      190ms  8.92%  runtime.(*gcBits).bitp (inline)      140ms  6.57% 51.17%      150ms  7.04%  runtime.findObject      130ms  6.10% 57.28%      130ms  6.10%  aeshashbody      100ms  4.69% 61.97%      810ms 38.03%  runtime.scanobject       90ms  4.23% 66.20%      230ms 10.80%  runtime.mallocgc       80ms  3.76% 69.95%       80ms  3.76%  runtime.markBits.isMarked (inline)       60ms  2.82% 72.77%       60ms  2.82%  runtime.nextFreeFast (inline) <\/code><\/pre>\n<ul>\n<li>\n<p><strong>\u041e\u0431\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f<\/strong>:<\/p>\n<ul>\n<li>\n<p><code>FastSyncMap<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b 3100ms CPU.<\/p>\n<\/li>\n<li>\n<p><code>sync.Map<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b 2130ms CPU.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438 CPU<\/strong>:<\/p>\n<ul>\n<li>\n<p>\u0412 \u043e\u0431\u043e\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0442\u0440\u0430\u0442\u0438\u0442\u0441\u044f \u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>runtime.mapaccess2<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c \u043a\u0430\u0440\u0442\u044b (<code>sync.Map<\/code> \u0438, \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b <code>FastSyncMap<\/code>).<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u0413\u0430\u0440bage Collection \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u044c\u044e<\/strong>:<\/p>\n<ul>\n<li>\n<p><code>gcDrain<\/code> \u0438 <code>scanobject<\/code> \u0442\u0430\u043a\u0436\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0442 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u0432 \u043e\u0431\u043e\u0438\u0445 \u043f\u0440\u043e\u0444\u0438\u043b\u044f\u0445, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044f \u043d\u0430 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u0443\u0447\u0430\u0441\u0442\u0438\u0435 \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0430 \u043c\u0443\u0441\u043e\u0440\u0430 (GC).<\/p>\n<\/li>\n<li>\n<p><code>runtime.procyield<\/code> \u0438 <code>aeshashbody<\/code> \u0442\u0430\u043a\u0436\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0442 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0430 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c\u0438.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>\u0418\u0434\u0435\u043c \u0434\u0430\u043b\u044c\u0448\u0435 &#8212; \u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u043e\u0444\u0438\u043b\u044c \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043e\u043a<\/p>\n<pre><code>go tool pprof fastsyncmap_block.prof File: lesson.test Type: delay Time: Jun 19, 2024 at 10:40am (MSK) Entering interactive mode (type \"help\" for commands, \"o\" for options) (pprof) top Showing nodes accounting for 3122.65ms, 100% of 3122.65ms total Dropped 2 nodes (cum &lt;= 15.61ms) Showing top 10 nodes out of 14       flat  flat%   sum%        cum   cum%  2076.23ms 66.49% 66.49%  2076.23ms 66.49%  sync.(*WaitGroup).Wait   703.08ms 22.52% 89.00%   703.08ms 22.52%  sync.(*Mutex).Lock (inline)   343.34ms 11.00%   100%   343.34ms 11.00%  runtime.chanrecv1          0     0%   100%   702.53ms 22.50%  lesson.(*FastSyncMap).Store          0     0%   100%  2419.57ms 77.48%  lesson.BenchmarkFastSyncMapWriteMillion          0     0%   100%   703.08ms 22.52%  lesson.BenchmarkFastSyncMapWriteMillion.func1          0     0%   100%   343.34ms 11.00%  runtime\/pprof.StopCPUProfile          0     0%   100%   702.53ms 22.50%  sync.(*Map).Store (inline)          0     0%   100%   702.53ms 22.50%  sync.(*Map).Swap          0     0%   100%  2076.23ms 66.49%  testing.(*B).RunParallel   go tool pprof syncmap_block.prof  File: lesson.test Type: delay Time: Jun 19, 2024 at 10:40am (MSK) Entering interactive mode (type \"help\" for commands, \"o\" for options) (pprof) top Showing nodes accounting for 7777.40ms, 100% of 7777.40ms total Dropped 2 nodes (cum &lt;= 38.89ms) Showing top 10 nodes out of 26       flat  flat%   sum%        cum   cum%  3550.66ms 45.65% 45.65%  3550.66ms 45.65%  sync.(*WaitGroup).Wait  3310.10ms 42.56% 88.21%  3310.10ms 42.56%  runtime.chanrecv1   916.65ms 11.79%   100%   916.65ms 11.79%  sync.(*Mutex).Lock (inline)          0     0%   100%   702.53ms  9.03%  lesson.(*FastSyncMap).Store          0     0%   100%  2609.71ms 33.56%  lesson.BenchmarkFastSyncMapWriteMillion          0     0%   100%   703.08ms  9.04%  lesson.BenchmarkFastSyncMapWriteMillion.func1          0     0%   100%  1626.74ms 20.92%  lesson.BenchmarkSyncMapWriteMillion          0     0%   100%   213.57ms  2.75%  lesson.BenchmarkSyncMapWriteMillion.func1          0     0%   100%  2624.31ms 33.74%  main.main          0     0%   100%  2624.31ms 33.74%  runtime.main <\/code><\/pre>\n<h4>\u0410\u043d\u0430\u043b\u0438\u0437 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432<\/h4>\n<ol>\n<li>\n<p><strong>\u041e\u0431\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u0435\u043a<\/strong>:<\/p>\n<ul>\n<li>\n<p><code>FastSyncMap<\/code>: 3122.65 ms<\/p>\n<\/li>\n<li>\n<p><code>sync.Map<\/code>: 7777.40 ms<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p><code>sync.Map<\/code> \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0435\u0435 \u043e\u0431\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u0435\u043a \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 <code>FastSyncMap<\/code>.<\/p>\n<ol start=\"2\">\n<li>\n<p><strong>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0443\u0437\u043b\u044b \u0437\u0430\u0434\u0435\u0440\u0436\u0435\u043a<\/strong>:<\/p>\n<ul>\n<li>\n<p>\u0412 <code>FastSyncMap<\/code> \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u0435\u043a \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 <code>sync.(*WaitGroup).Wait<\/code> (66.49%) \u0438 <code>sync.(*Mutex).Lock<\/code> (22.52%).<\/p>\n<\/li>\n<li>\n<p>\u0412 <code>sync.Map<\/code> \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u0435\u043a \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 <code>sync.(*WaitGroup).Wait<\/code> (45.65%) \u0438 <code>runtime.chanrecv1<\/code> (42.56%).<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<h4>\u041e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0435<\/h4>\n<ul>\n<li>\n<p><strong>\u0412\u0440\u0435\u043c\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f WaitGroup<\/strong>:<\/p>\n<ul>\n<li>\n<p>\u041e\u0431\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 <code>sync.WaitGroup<\/code> \u0434\u043b\u044f \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0433\u043e\u0440\u0443\u0442\u0438\u043d, \u0447\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u043c\u0443 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f. \u0412 <code>FastSyncMap<\/code> \u044d\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 2076.23 ms (66.49%), \u0432 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a \u0432 <code>sync.Map<\/code> \u044d\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 3550.66 ms (45.65%).<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u0412\u0440\u0435\u043c\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043e\u043a Mutex<\/strong>:<\/p>\n<ul>\n<li>\n<p>\u0412 <code>FastSyncMap<\/code> \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 <code>sync.Mutex<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u043d\u0430 703.08 ms (22.52%), \u0432 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a \u0432 <code>sync.Map<\/code> \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u0438\u0437-\u0437\u0430 <code>sync.Mutex<\/code> \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 916.65 ms (11.79%).<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u0412\u0440\u0435\u043c\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u043a\u0430\u043d\u0430\u043b\u043e\u0432<\/strong>:<\/p>\n<ul>\n<li>\n<p>\u0412 <code>sync.Map<\/code> \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f (3310.10 ms, 42.56%) \u0443\u0445\u043e\u0434\u0438\u0442 \u043d\u0430 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u0432 \u043a\u0430\u043d\u0430\u043b\u0430\u0445, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u0441 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044f\u043c\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u044b\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u043e\u043c \u043a \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c \u043a\u0430\u0440\u0442\u044b.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h4>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h4>\n<ol>\n<li>\n<p><code>FastSyncMap<\/code>:<\/p>\n<ul>\n<li>\n<p>\u0418\u043c\u0435\u0435\u0442 \u043c\u0435\u043d\u044c\u0448\u0435\u0435 \u043e\u0431\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u0435\u043a (3122.65 ms) \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 <code>sync.Map<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u0441 <code>sync.WaitGroup<\/code> (66.49%) \u0438 <code>sync.Mutex<\/code> (22.52%).<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><code>sync.Map<\/code>:<\/p>\n<ul>\n<li>\n<p>\u0418\u043c\u0435\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0435\u0435 \u043e\u0431\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u0435\u043a (7777.40 ms).<\/p>\n<\/li>\n<li>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u0441 <code>sync.WaitGroup<\/code> (45.65%) \u0438 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435\u043c \u0432 \u043a\u0430\u043d\u0430\u043b\u0430\u0445 (42.56%).<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/822861\/\"> https:\/\/habr.com\/ru\/articles\/822861\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 &#8212; \u044d\u0442\u043e \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u0441\u043f\u043e\u0440\u0442\u0438\u0432\u043d\u044b\u0439 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442, \u043d\u0430\u043a\u0438\u0434\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0434 \u0432\u0435\u0447\u0435\u0440 \u043d\u0430 \u043a\u043e\u043b\u0435\u043d\u043a\u0435 \u0441 \u0446\u0435\u043b\u044c\u044e \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>\u0417\u0430\u0434\u0430\u0447\u0430 \u0431\u044b\u043b\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0430\u043d\u0430\u043b\u043e\u0433 sync.Map \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u043d\u044b\u0439 \u043f\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043a \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u0443, \u0441\u043f\u043e\u0440\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0430 \u0440\u0430\u0434\u0438.<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u0440\u0430\u0437\u0443 \u043a \u043a\u043e\u0434\u0443 \u0438 \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0430\u043c:<\/p>\n<pre><code class=\"go\">package main  import ( \"hash\/fnv\" \"sync\" )  type bucket struct { data sync.Map }  type FastSyncMap struct { buckets []*bucket }  func NewSyncMap(bucketCount int) *FastSyncMap { buckets := make([]*bucket, bucketCount) for i := range buckets { buckets[i] = &amp;bucket{} } return &amp;FastSyncMap{buckets: buckets} }  func (m *FastSyncMap) hash(key string) int { h := fnv.New32a() h.Write([]byte(key)) return int(h.Sum32()) % len(m.buckets) }  func (m *FastSyncMap) Store(key string, value interface{}) { index := m.hash(key) b := m.buckets[index] b.data.Store(key, value) }  func (m *FastSyncMap) Load(key string) (value interface{}, ok bool) { index := m.hash(key) b := m.buckets[index] return b.data.Load(key) }<\/code><\/pre>\n<p>\u0412\u043e\u0442 \u0442\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a:<\/p>\n<pre><code class=\"go\">package main  import ( \"strconv\" \"sync\" \"testing\" )  var data = map[string]int{ \"key-001\": 437, \"key-002\": 384, \"key-003\": 983, \"key-004\": 543, \"key-005\": 276, \"key-006\": 128, \"key-007\": 753, \"key-008\": 832, \"key-009\": 621, \"key-010\": 519, \"key-011\": 407, \"key-012\": 905, \"key-013\": 132, \"key-014\": 658, \"key-015\": 294, \"key-016\": 745, \"key-017\": 389, \"key-018\": 910, \"key-019\": 482, \"key-020\": 371, \"key-021\": 648, \"key-022\": 573, \"key-023\": 781, \"key-024\": 452, \"key-025\": 390, \"key-026\": 167, \"key-027\": 296, \"key-028\": 854, \"key-029\": 731, \"key-030\": 513, \"key-031\": 249, \"key-032\": 675, \"key-033\": 890, \"key-034\": 412, \"key-035\": 567, \"key-036\": 712, \"key-037\": 361, \"key-038\": 284, \"key-039\": 946, \"key-040\": 709, \"key-041\": 541, \"key-042\": 673, \"key-043\": 325, \"key-044\": 498, \"key-045\": 823, \"key-046\": 654, \"key-047\": 832, \"key-048\": 276, \"key-049\": 792, \"key-050\": 619, \"key-051\": 485, \"key-052\": 527, \"key-053\": 831, \"key-054\": 491, \"key-055\": 350, \"key-056\": 764, \"key-057\": 539, \"key-058\": 204, \"key-059\": 926, \"key-060\": 687, \"key-061\": 498, \"key-062\": 143, \"key-063\": 359, \"key-064\": 871, \"key-065\": 604, \"key-066\": 318, \"key-067\": 425, \"key-068\": 691, \"key-069\": 536, \"key-070\": 174, \"key-071\": 523, \"key-072\": 680, \"key-073\": 352, \"key-074\": 870, \"key-075\": 429, \"key-076\": 237, \"key-077\": 491, \"key-078\": 391, \"key-079\": 702, \"key-080\": 826, \"key-081\": 318, \"key-082\": 563, \"key-083\": 496, \"key-084\": 791, \"key-085\": 142, \"key-086\": 380, \"key-087\": 943, \"key-088\": 467, \"key-089\": 389, \"key-090\": 905, \"key-091\": 281, \"key-092\": 478, \"key-093\": 654, \"key-094\": 193, \"key-095\": 849, \"key-096\": 740, \"key-097\": 268, \"key-098\": 431, \"key-099\": 739, \"key-100\": 511, \"key-101\": 234, \"key-102\": 593, \"key-103\": 800, \"key-104\": 137, \"key-105\": 405, \"key-106\": 872, \"key-107\": 364, \"key-108\": 230, \"key-109\": 793, \"key-110\": 649, \"key-111\": 507, \"key-112\": 391, \"key-113\": 170, \"key-114\": 923, \"key-115\": 478, \"key-116\": 375, \"key-117\": 682, \"key-118\": 195, \"key-119\": 735, \"key-120\": 341, \"key-121\": 263, \"key-122\": 498, \"key-123\": 149, \"key-124\": 517, \"key-125\": 350, \"key-126\": 630, \"key-127\": 809, \"key-128\": 472, \"key-129\": 367, \"key-130\": 953, \"key-131\": 284, \"key-132\": 576, \"key-133\": 395, \"key-134\": 719, \"key-135\": 364, \"key-136\": 157, \"key-137\": 861, \"key-138\": 495, \"key-139\": 267, \"key-140\": 436, \"key-141\": 513, \"key-142\": 722, \"key-143\": 184, \"key-144\": 637, \"key-145\": 912, \"key-146\": 501, \"key-147\": 294, \"key-148\": 178, \"key-149\": 843, \"key-150\": 671, }  func BenchmarkMySyncMap(b *testing.B) { m := NewSyncMap(len(data)) b.ResetTimer()  for i := 0; i &lt; b.N; i++ { for k, v := range data { m.Store(k, v) }  for k, v := range data { v2, ok := m.Load(k) if !ok || v2 != v { b.Fatalf(\"key %s not found in cache (%v) or incorrect value: %v\", k, ok, v2) } } } }  func BenchmarkGoSyncMap(b *testing.B) { var m sync.Map b.ResetTimer()  for i := 0; i &lt; b.N; i++ { for k, v := range data { m.Store(k, v) }  for k, v := range data { v2, ok := m.Load(k) if !ok || v2 != v { b.Fatalf(\"key %s not found in cache (%v) or incorrect value: %v\", k, ok, v2) } } } }  func BenchmarkMySyncMapParallel(b *testing.B) { m := NewSyncMap(150 * 2) b.ResetTimer()  b.RunParallel(func(pb *testing.PB) { for pb.Next() { for k, v := range data { m.Store(k, v) }  for k, v := range data { v2, ok := m.Load(k) if !ok || v2 != v { b.Fatalf(\"key %s not found in cache (%v) or incorrect value: %v\", k, ok, v2) } } } }) }  func BenchmarkGoSyncMapParallel(b *testing.B) { var m sync.Map b.ResetTimer() b.RunParallel(func(pb *testing.PB) { for pb.Next() { for k, v := range data { m.Store(k, v) }  for k, v := range data { v2, ok := m.Load(k) if !ok || v2 != v { b.Fatalf(\"key %s not found in cache (%v) or incorrect value: %v\", k, ok, v2) } } } }) }  func BenchmarkFastSyncMapWriteMillion(b *testing.B) { m := NewSyncMap(150 * 2) totalEntries := 1000000 b.ResetTimer()  b.RunParallel(func(pb *testing.PB) { for pb.Next() { for i := 0; i &lt; totalEntries; i++ { key := strconv.Itoa(i) m.Store(key, i) m.Load(key) } } }) }  func BenchmarkSyncMapWriteMillion(b *testing.B) { var m sync.Map totalEntries := 1000000 b.ResetTimer()  b.RunParallel(func(pb *testing.PB) { for pb.Next() { for i := 0; i &lt; totalEntries; i++ { key := strconv.Itoa(i) m.Store(key, i) m.Load(key) } } }) }<\/code><\/pre>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0430 \u043d\u0430 \u043c\u043e\u0435\u043c \u041f\u041a<\/p>\n<pre><code class=\"go\">goos: linux goarch: amd64 pkg: lesson cpu: 12th Gen Intel(R) Core(TM) i7-12700K BenchmarkMySyncMap BenchmarkMySyncMap-20                      74986        15030 ns\/op BenchmarkGoSyncMap BenchmarkGoSyncMap-20                      76708        15605 ns\/op BenchmarkMySyncMapParallel BenchmarkMySyncMapParallel-20             479565         2518 ns\/op BenchmarkGoSyncMapParallel BenchmarkGoSyncMapParallel-20             455433         2679 ns\/op BenchmarkFastSyncMapWriteMillion BenchmarkFastSyncMapWriteMillion-20            4    264691361 ns\/op BenchmarkSyncMapWriteMillion BenchmarkSyncMapWriteMillion-20                3    458739675 ns\/op PASS<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0437\u0430\u043f\u0438\u0441\u0438\\\u0447\u0442\u0435\u043d\u0438\u0438 \u0432 \u043e\u0434\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430\u044f sync.Map \u0432\u044b\u0438\u0433\u0440\u044b\u0432\u0430\u0435\u0442.<br \/>\u041f\u0440\u0438 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u0441 \u043c\u0430\u043b\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439 fast sync map \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u043d\u0430 2%.<br \/>\u041f\u0440\u0438 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u0441 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439 \u0432 \u043c\u0438\u043b\u043b\u0438\u043e\u043d \u0437\u0430\u043f\u0438\u0441\u0435\u0439 fast sync map \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u043d\u0430 73%.<\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u0435 \u043c\u043e\u0435\u0439 \u0442\u0430\u0447\u043a\u0438, \u0433\u0434\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u043b\u0441\u044f \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a:<\/p>\n<pre><code class=\"bash\">$ lscpu Architecture:            x86_64   CPU op-mode(s):        32-bit, 64-bit   Address sizes:         46 bits physical, 48 bits virtual   Byte Order:            Little Endian CPU(s):                  20   On-line CPU(s) list:   0-19 Vendor ID:               GenuineIntel   Model name:            12th Gen Intel(R) Core(TM) i7-12700K     CPU family:          6     Model:               151     Thread(s) per core:  2     Core(s) per socket:  12     Socket(s):           1     Stepping:            2     CPU max MHz:         5000,0000     CPU min MHz:         800,0000     BogoMIPS:            7219.20     Flags:               fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bt                          s rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm sse4_1 sse4_2 x2apic movbe popcnt                           tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx                          2 smep bmi2 erms invpcid rdseed adx smap clflushopt clwb intel_pt sha_ni xsaveopt xsavec xgetbv1 xsaves split_lock_detect avx_vnni dtherm ida arat pln pts hwp hwp_notify hwp_act_window h                          wp_epp hwp_pkg_req hfi vnmi umip pku ospke waitpkg gfni vaes vpclmulqdq tme rdpid movdiri movdir64b fsrm md_clear serialize pconfig arch_lbr ibt flush_l1d arch_capabilities Virtualization features:    Virtualization:        VT-x Caches (sum of all):        L1d:                   512 KiB (12 instances)   L1i:                   512 KiB (12 instances)   L2:                    12 MiB (9 instances)   L3:                    25 MiB (1 instance) NUMA:                       NUMA node(s):          1   NUMA node0 CPU(s):     0-19 Vulnerabilities:            Gather data sampling:  Not affected   Itlb multihit:         Not affected   L1tf:                  Not affected   Mds:                   Not affected   Meltdown:              Not affected   Mmio stale data:       Not affected   Retbleed:              Not affected   Spec rstack overflow:  Not affected   Spec store bypass:     Mitigation; Speculative Store Bypass disabled via prctl   Spectre v1:            Mitigation; usercopy\/swapgs barriers and __user pointer sanitization   Spectre v2:            Mitigation; Enhanced \/ Automatic IBRS; IBPB conditional; RSB filling; PBRSB-eIBRS SW sequence; BHI BHI_DIS_S   Srbds:                 Not affected   Tsx async abort:       Not affected<\/code><\/pre>\n<pre><code class=\"bash\">sudo lshw -short -C memory H\/W path           Device     Class          Description ======================================================== \/0\/0                          memory         64KiB BIOS \/0\/3b                         memory         40GiB System Memory \/0\/3b\/0                       memory         8GiB DIMM Synchronous 4800 MHz (0,2 ns) \/0\/3b\/1                       memory         16GiB DIMM Synchronous 4800 MHz (0,2 ns) \/0\/3b\/2                       memory         16GiB DIMM Synchronous 4800 MHz (0,2 ns) \/0\/3b\/3                       memory         [empty] \/0\/4b                         memory         384KiB L1 cache \/0\/4c                         memory         256KiB L1 cache \/0\/4d                         memory         10MiB L2 cache \/0\/4e                         memory         25MiB L3 cache \/0\/4f                         memory         128KiB L1 cache \/0\/50                         memory         256KiB L1 cache \/0\/51                         memory         2MiB L2 cache \/0\/52                         memory   <\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-379174","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/379174","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=379174"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/379174\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=379174"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=379174"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=379174"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}