当前位置: 首页 > 网络应用技术

进行并行阅读和写作Sync.map功能强大

时间:2023-03-09 01:10:42 网络应用技术

  在上一个“为什么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已包括在内。