在上一个“为什么Go Map and Slice非线程安全性?在文章中,我们讨论了MAP和SLICE非网络安全性问题的问题。基于此,这是两个当前使用的两个最同时的支持模型行业已扩展。
他们是:
有了选择,总会选择困难。这两种类型的选择如何,谁的表现更好?我有一个朋友说标准图书馆同步。映射性能很好,不要使用它。我听到谁...
今天,炸鱼将带您揭示Go Sync.map。我们将首先了解如何使用各种类型的GO地图,以及谁的性能是最好的!
然后,根据每个地图性能分析的结果,Sync.map的源代码是针对性的,以了解原因。
开始快乐地吮吸鱼的道路。
在GO官方文件中明确指出,该地图类型的一些建议:
同时,地图类型还优化了以下场景的性能:
与使用单独的Mutex或rwmutex的GO地图相比,使用地图类型可以大大减少锁。
在收听官方文档引入了很多好处之后,他没有谈论缺点,性能优化的优势是真实且可信的。
首先,我们定义了基本数据结构:
在支持方法方面,我们所有人都写了相应的添加,删除和更改的相应方法。用于随后的压力测试(仅一些代码显示):
其余类型的方法基本上是相似的,因此在此不显示重复长度的问题。
压力测试方法的基本代码如下:
这主要是添加,删除和修改的代码和压力测量方法的准备。大白老板的GO19示例/基准图计划直接重复了压力测试代码。
您也可以使用GO提供的go_bench_test.go。有兴趣的合作伙伴可以自己拉下来尝试。
1)写:
Mutex,最快的是本机映射+读写锁(rwmutex)。
总体排序(从慢速到快速)为:Syncmapstore <mapstore <rwmapstore。
2)查找:
阅读和写作锁。最快的是类型。
总体顺序为:maplookup <rwmaplookup <syncmaplookup。
3)删除:
最快的类型是类型。
总体顺序为:rwmapdelete <mapdelete <syncmapdelete。
根据上述压力测试结果,我们可以得到类型:
因此,在实际的业务场景中,它是一个场景,具有更多的写作和更少的写作,建议使用该类型。
但是,如果有很多场景,例如多个循环写作的多个goroutine批次,建议开放另一种方式,并且性能不会难以忍受(没有性能要求不同)。
显然,在测试结果之后如何进行测试。我们需要进一步挖掘并知道为什么。
为什么测试结果的类型如此“部分”,为什么操作性如此之高,并且操作性性能很糟糕。他是如何设计的?
该类型的基础数据结构如下:
在阅读和肮脏中,涉及一个结构化体:
它包含一个指针P,该指针用于指向用户的元素(键)的值。
建议您了解阅读,肮脏,进入和看不清,饮食的效果会更好,并且将来会围绕这些概念而流动。
在焦点中,地图类型中有两个“地图”。一个称为读取,另一个称为肮脏,而长则几乎是相同的:
2同步地图
当我们从同步类型中读取数据时,它将首先检查所需元素是否包含读取中所需的元素:读取:
Sync.map的阅读性能如此之高的原因是,巧妙的读取设计是一个缓存层,它提供了快速的路径搜索。
同时,它结合了修改后的属性,支持设施解决了锁定所有阅读的问题,并实现了阅读此场景的高度性能。
我们直接注意商店方法的类型。该方法的作用是添加或更新元素。
源代码如下:
呼叫方法检查此元素是否存在。如果您存在并且未标记为已删除,则尝试存储它。
如果该元素不存在或已被标记为已删除,请继续进行以下过程:
由于它已经达到了肮脏的过程,因此该方法直接调用了锁定方法以确保数据安全性的方法,这也是强调性能不佳的第一个行为。
它分为以下三个处理分支:
我们认为,编写该过程的总体过程是:
回到最初的话题,为什么他有这么多写作表现。
最好知道这种类型不适合编写更多。最好读写少。
如果有大量数据,您需要考虑是否可以接受数据复制数据的意外抖动。
目前,一些朋友可能正在思考。在写作过程中,理论上和删除不会太远。如何删除表演似乎还可以。油腻的是什么?
源代码如下:
删除是一个标准开口,并且仍在阅读以检查元素是否存在。
如果存在,该呼叫被标记为删除,这非常有效。它可以在读取的元素中清楚地删除,并且性能非常好。
如果它不存在,也就是说,对于肮脏的过程:
如果读取中不存在该元素,则脏物不是空的,并且读取和肮脏是不一致的(使用修订),这表明有必要操作肮脏和上锁。
重复双重检查,如果读取仍然不存在。
应该注意的是,删除频率较高的方法:
此方法是将entry.p设置为nil,并将其标记为已删除(删除状态)而不是真正删除。
注意:不要滥用。从字节共享的情况下,它们将连接作为键输入,因此它们与此连接有关,例如:Buffer的内存将永远不会发布...
通过阅读本文,我们清楚地阐明了本机地图 +相互锁定/读写锁之间的性能。
尽管标准库支持并发的阅读和写作图,但它更适合阅读更多场景,因为他所写的表演相对较差,并且在使用时应考虑这一点。
此外,我们对性能差异进行了深入的源分析,并了解了其背后的快速和缓慢的原因,并意识到了它知道它的原因。
令人担忧的是,看到地图的复杂性真的很担心。每个人都认为,如果这篇文章很好,欢迎与更多的Go爱好者分享:)
如果您有任何疑问,请欢迎评论领域的反馈和交流,最好的关系是相互实现。对您的称赞是制造炸鱼的最大动力。感谢您的支持。
文章不断更新,您可以搜索[大脑以炸鱼]来阅读。本文githubgithub.com/eddycjy/blog已包括在内。