为什么 Golang Fasthttp 选择使用 slice 而非 map 存储请求数据

这篇具有很好参考价值的文章主要介绍了为什么 Golang Fasthttp 选择使用 slice 而非 map 存储请求数据。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

为什么 Golang Fasthttp 选择使用 slice 而非 map 存储请求数据,golang,fasthttp,http,web,webframework,程序人生


Fasthttp 是一个高性能的 Golang HTTP 框架,它在设计上做了许多优化以提高性能。其中一个显著的设计选择是使用 slice 而非 map 来存储数据,尤其是在处理 HTTP headers 时。

为什么呢?

本文将从简单到复杂,逐步剖析为什么 Fasthttp 选择使用 slice 而非 map,并通过代码示例解释这一选择背后高性能的原因

Slice vs Map:基本概念

首先,这个设计选择背后有着深思熟虑的考量,主要围绕性能优化展开。在深入探讨之前,我们需要理解 slice 和 map 在 Go 语言中的基本概念和性能特点。

为什么 Golang Fasthttp 选择使用 slice 而非 map 存储请求数据,golang,fasthttp,http,web,webframework,程序人生

  • Slice:Slice 是对数组的封装,它提供了一个动态大小的、灵活的视图。Slices 的底层实际上是数组,这意味着它们的元素在内存中是连续存储的。
  • Map:Map 是一种无序的键值对的集合,它通过哈希表实现。Map 提供了快速的查找、添加和删除操作,但这些操作的性能并不总是稳定。

内存分配和性能

在高性能的应用场景中,内存分配和回收是性能的关键因素之一。Fasthttp 在这方面做了优化:

Slice 的内存效率

由于 slice 的元素在内存中是连续存储的,它们访问速度快,且能有效利用 CPU 缓存。此外,slice 可以通过重新切片来复用已有的数组,减少内存分配和垃圾回收的压力。

Map 的内存开销

相比之下,map 的内存开销较大。在 map 中,键和值通常是散布在内存中的,这导致 CPU 缓存利用率不高。而且,map 的增长通常涉及重新哈希和重新分配内存,这些操作在性能敏感的应用中可能成为瓶颈。

Fasthttp 中的 SliceMap

Fasthttp 选择使用自定义的 sliceMap 结构来存储键值对,而非标准的 map。下面是 sliceMap 的一个简化版本和它的 Add 方法:

type kv struct {
    key []byte
    value []byte
}

type sliceMap []kv

func (sm *sliceMap) Add(k, v []byte) {
    kvs := *sm
    if cap(kvs) > len(kvs) {
        kvs = kvs[:len(kvs)+1]
    } else {
        kvs = append(kvs, kv{})
    }
    kv := &kvs[len(kvs)-1]
    kv.key = append(kv.key[:0], k...)
    kv.value = append(kv.value[:0], v...)
    *sm = kvs
}

在这个设计中,sliceMap 通过以下方式优化性能:

减少内存分配

为什么 Golang Fasthttp 选择使用 slice 而非 map 存储请求数据,golang,fasthttp,http,web,webframework,程序人生

通过在现有的 slice 上进行操作,sliceMap 尽可能地复用内存。当容量足够时,它通过重新切片 kvs = kvs[:len(kvs)+1] 来扩展 slice,避免了额外的内存分配。

减少垃圾回收压力

由于 slice 的元素是连续存储的,它可以更有效地被垃圾回收器处理,减少了垃圾回收的开销。而且,由于内存是复用的,垃圾回收的次数也大大减少。

性能优化的深层原因

Fasthttp 使用 sliceMap 而非 map 的决策不仅仅是基于内存和性能的考量,还有更深层的原因:

HTTP Headers 的特性

在处理 HTTP 请求时,通常 headers、query 参数或 cookies 的数量并不多。这意味着即使使用线性搜索,查找效率也不会成为性能瓶颈。

相比之下,虽然 hash map 提供了理论上接近 O(1) 的查找效率,但实际使用中也有其开销和复杂性。

  • 首先,hash map 的哈希计算本身就需要时间。
  • 其次,哈希碰撞时,hash map 要额外处理来解决碰撞,这可能涉及到链表遍历或重新哈希等操作。

这些因素在元素数量较少时可能会抵消 hash map 在查找效率上的理论优势,而 slice 则才是更优质的选择。

CPU 预加载特性

由于 slice 的内存布局是连续的,它符合 CPU 缓存的工作原理,即一次性加载相邻数据。这种连续性使得 CPU 在访问一个 slice 元素后,能预加载相邻元素到缓存中,提高后续访问的速度。

因此,顺序访问 slice 时,缓存命中率高,减少了对主内存的访问次数,从而提高了性能。

结论

Fasthttp 的设计选择反映了对性能细节的深入理解和精心优化。通过使用 slice 而非 map,Fasthttp 在内存分配、垃圾回收以及 CPU 缓存利用等方面实现了优化,为高性能的 HTTP 应用提供了坚实的基础。这种设计不仅仅是技术上的选择,更是对实际应用场景和性能需求的深入洞察。文章来源地址https://www.toymoban.com/news/detail-813982.html

到了这里,关于为什么 Golang Fasthttp 选择使用 slice 而非 map 存储请求数据的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 为什么越来越多的开发者放弃使用Postman,而选择Apifox

    1、Postman + Swagger + Mock + JMeter 作为一个后端开发,我做的大部分项目一般都是基于 Swagger 来管理 API 文档,基于 Postman 来做接口调试,基于 JMeter 来做接口性能测试,基于 RAP 等工具 Mock API 数据。 2、存在的问题 (1)多系统数据不互通 API设计者、前端开发、后端开发、测试人

    2024年01月20日
    浏览(43)
  • 【Golang 接口自动化00】为什么要用Golang做自动化?

    目录 为什么使用Golang做自动化 最终想实现的效果 怎么做? 写在后面  资料获取方法 顺应公司的趋势学习了Golang之后,因为没有太多时间和项目来实践,怕止步于此、步Java缺少练习遗忘殆尽的后尘,决定利用工作之余的时间把此前用Python的写的自动化使用golang进行重构。

    2024年02月15日
    浏览(56)
  • Golang对比Java、python为什么要保留指针

    平时我们在Golang使用指针一般是为了以下的情况: 方法直接修改原来对象 保证参数传递的自由,可以在传递重量级对象时使用指针 但Go 保留指针不仅仅是为了解决传递参数的问题,还跟它的语言特性有密不可分的联系。 Go 里面的变量是 值语义 ,这个跟 C/C++是一脉相承的。

    2024年01月17日
    浏览(61)
  • Golang 中的 map 为什么是并发不安全的?

      golang 中的 map 是并发不安全的,多个 go 协程同时对同一个 map 进行读写操作时,会导致数据竞争(data race)问题,程序会 panic。   如果一个协程正在写入 map,而另一个协程正在读取或写入 map,那么就有可能出现一些未定义的行为,例如:读取到的值可能是过期的、不

    2024年02月05日
    浏览(49)
  • 为什么选择新风机?

      现如今,新风机已经是很多场地的熟客了,那大家可能疑惑为什么选择新风机呢?那就让我揭晓答案吧!新风机有很多益处,让我大致简述一下吧。 改善室内空气质量:新风机能够引入新鲜的外界空气,并排除室内的污浊空气,有效净化空气,降低颗粒物、细菌、异味等有

    2024年02月11日
    浏览(48)
  • 【Golang】Golang进阶系列教程--为什么 Go 不支持 []T 转换为 []interface

    在 Go 中,如果 interface{} 作为函数参数的话,是可以传任意参数的,然后通过类型断言来转换。 举个例子: 不管是传 int 还是 string,最终都能输出正确结果。 那么,既然是这样的话,我就有一个疑问了,拿出我举一反三的能力。是否可以将 []T 转换为 []interface 呢? 比如下面

    2024年02月15日
    浏览(57)
  • 我为什么选择在大二实习?

    本文已收录于专栏 ⭐️ 《沈七杂谈》⭐️ 时间好快,转眼已经入职一个月了,实习要比想象的忙很多,所以一直没腾出时间写篇经验贴。 恰逢五一小长假,正好总结一下为在大二能找到实习所做一切的心路历程。 先简单介绍一下楼主,目前烂本大二在读,专业是软件工程

    2024年02月03日
    浏览(39)
  • 为什么选择网络安全?为什么说网络安全是IT行业最后的红利?

    一、为什么选择网络安全? 这几年随着我国《国家网络空间安全战略》《网络安全法》《网络安全等级保护2.0》等一系列政策/法规/标准的持续落地,网络安全行业地位、薪资随之水涨船高。 未来3-5年,是安全行业的黄金发展期,提前踏入行业,能享受行业发展红利。 二、

    2024年02月11日
    浏览(54)
  • 【Golang】Golang进阶系列教程--为什么说 Go 语言字符串是不可变的?

    最近有读者留言说,平时在写代码的过程中,是会对字符串进行修改的,但网上都说 Go 语言字符串是不可变的,这是为什么呢? 这个问题本身并不困难,但对于新手来说确实容易产生困惑,今天就来回答一下。 首先来看看它的底层结构: 和切片的结构很像,只不过少了一个

    2024年02月14日
    浏览(47)
  • 为什么选择 Next.js 框架?

    Next.js 框架作为一种强大而受欢迎的工具,为开发人员提供了许多优势和便利。本文将探讨 Next.js 框架的优点,并解释为什么选择 Next.js 是一个明智的决策。 文档:https://nextjs.org/docs Next.js 框架提供了先进的服务端渲染(SSR)和静态生成(SSG)能力,使得我们能够在服务器上生

    2024年02月12日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包