当前位置: 首页 > wzjs >正文

企业展示网站互联网推广运营是干什么的

企业展示网站,互联网推广运营是干什么的,深圳市招聘网站,苏州建设银行招聘网站项目地址:https://github.com/gone-io/gone 原文地址:https://github.com/gone-io/goner/blob/main/gin/benchmark_test.md Gone-Gin 性能测试报告 文章目录 Gone-Gin 性能测试报告简介实现原理核心组件工作流程响应处理机制 性能测试测试环境测试用例测…

项目地址:https://github.com/gone-io/gone

原文地址:https://github.com/gone-io/goner/blob/main/gin/benchmark_test.md

Gone-Gin 性能测试报告

文章目录

  • Gone-Gin 性能测试报告
    • 简介
    • 实现原理
      • 核心组件
      • 工作流程
      • 响应处理机制
    • 性能测试
      • 测试环境
      • 测试用例
        • 测试代码示例
          • 请求结构体定义
          • Gone-Gin 处理函数
          • 原生 Gin 处理函数
          • 基准测试函数
        • HTTP 注入器核心代码
        • 代理机制核心代码
      • 测试结果
      • 结果分析
    • 优化建议
    • 结论

简介

Gone-Gin 是基于 Gin 框架的扩展,它提供了更加便捷的依赖注入和参数绑定功能,使得开发者可以更加专注于业务逻辑的实现,而不必关心请求参数的解析和绑定过程。本文档将介绍 Gone-Gin 的实现原理以及与原生 Gin 的性能对比。

实现原理

核心组件

  1. HTTP 注入器 (HttpInjector)

    • 负责将 HTTP 请求中的参数注入到处理函数的参数中
    • 支持从不同来源(Body、Header、Query、Param、Cookie)注入参数
    • 通过反射机制实现参数的自动绑定和类型转换
  2. 代理 (Proxy)

    • 将用户定义的处理函数转换为 Gin 兼容的处理函数
    • 支持多种函数签名,提供更灵活的编程模式
    • 处理函数执行结果的统一响应处理
  3. 响应处理器 (Responer)

    • 负责将处理函数的返回值转换为 HTTP 响应
    • 支持多种返回值类型,包括结构体、Map、切片、错误等
    • 提供统一的响应格式,简化错误处理
    • 支持自定义响应包装函数,灵活定制返回格式
    • 内置对业务错误和系统错误的处理机制
    • 支持流式响应(SSE)和文件下载等高级功能

工作流程

  1. 用户定义处理函数,使用 gone:"http,xxx" 标签指定参数来源
  2. Gone-Gin 通过代理机制将用户函数转换为 Gin 兼容的处理函数
  3. 请求到达时,HTTP 注入器解析请求并将参数注入到用户函数中
  4. 用户函数执行完毕后,结果被响应处理器(Responer)统一处理并返回给客户端

响应处理机制

响应处理器(Responer)是 Gone-Gin 的核心组件之一,它负责将处理函数的返回值转换为 HTTP 响应。相比原生 Gin 需要手动构造响应,Gone-Gin 的响应处理机制更加智能和灵活:

  1. 自动类型识别

    • 结构体、Map、切片、数组等复杂类型自动转换为 JSON 响应
    • 基本类型(如字符串、数字等)自动转换为文本响应
    • 错误类型自动处理为错误响应,并根据错误类型设置适当的状态码
  2. 统一响应格式

    • 默认提供统一的响应格式 {"code": 0, "msg": "", "data": ...}
    • 支持通过配置关闭统一格式,直接返回原始数据
    • 支持自定义响应包装函数,灵活定制返回格式
  3. 错误处理机制

    • 区分业务错误(BusinessError)和系统错误(InnerError)
    • 业务错误会返回给客户端,包含错误码、错误信息和相关数据
    • 系统错误会被适当处理,避免敏感信息泄露,同时记录详细日志
  4. 高级功能支持

    • 支持流式响应(SSE),自动处理 Channel 类型的返回值
    • 支持文件下载,自动处理 io.Reader 类型的返回值
    • 支持多返回值处理,自动识别和处理错误

性能测试

测试环境

goos: darwin
goarch: arm64
cpu: Apple M1 Pro

测试用例

我们设计了四个基准测试用例来比较 Gone-Gin 和原生 Gin 的性能:

  1. BenchmarkProcessRequestWithInject:使用 Gone-Gin 处理完整的 HTTP 请求
  2. BenchmarkProcessRequestWithOriGin:使用原生 Gin 处理完整的 HTTP 请求
  3. BenchmarkProxyGinHandlerFunc:测试 Gone-Gin 代理机制的性能
  4. BenchmarkCallOriGinHandlerFunc:测试原生 Gin 处理函数的性能
测试代码示例
请求结构体定义
type Req struct {A int    `json:"a,omitempty"`B int    `json:"b,omitempty"`C int    `json:"c,omitempty"`D int    `json:"d,omitempty"`E string `json:"e,omitempty"`F string `json:"f,omitempty"`
}
Gone-Gin 处理函数
// Gone-gin 的 http 处理函数
func (c *ctr) httpHandler(in struct {req *Req `gone:"http,body"`
}) string {return "ok"
}
原生 Gin 处理函数
// 原生 Gin 处理函数
func originHandler(c *gin.Context) {var req Reqerr := c.ShouldBindJSON(&req)if err != nil {c.JSON(http.StatusBadRequest, err.Error())return}c.String(http.StatusOK, "ok")
}
基准测试函数
// BenchmarkProcessRequestWithInject 测试 使用 gone-gin 处理请求
func BenchmarkProcessRequestWithInject(b *testing.B) {_ = os.Setenv("GONE_SERVER_SYS-MIDDLEWARE_DISABLE", "true")_ = os.Setenv("GONE_SERVER_RETURN_WRAPPED-DATA", "false")gone.NewApp(gin.Load, tracer.Load).Load(&ctr{}).Run(func(httpHandler http.Handler) {b.ResetTimer()for n := 0; n < b.N; n++ {b.StopTimer()request := buildRequest()response := buildResponse()b.StartTimer()httpHandler.ServeHTTP(response, request)}})
}// BenchmarkProcessRequestWithOriGin 测试 使用 原生 gin 处理请求
func BenchmarkProcessRequestWithOriGin(b *testing.B) {engine := gin.New()engine.POST("/api/test", originHandler)b.ResetTimer()for n := 0; n < b.N; n++ {b.StopTimer()request := buildRequest()response := buildResponse()b.StartTimer()engine.ServeHTTP(response, request)}
}
HTTP 注入器核心代码
// HTTP 注入器的核心实现 - 处理 Body 参数注入
func (s *httpInjector) injectBody(kind, key string, field reflect.StructField) (fn BindFieldFunc, err error) {if s.isInjectedBody {return nil, cannotInjectBodyMoreThanOnce(field.Name)}t := field.Typeswitch t.Kind() {case reflect.Struct, reflect.Map, reflect.Slice:return func(ctx *gin.Context, structVale reflect.Value) error {v := fieldByIndexFromStructValue(structVale, field.Index, field.IsExported(), field.Type)body := reflect.New(t).Interface()if err := ctx.ShouldBind(body); err != nil {return NewParameterError(err.Error())}v.Set(reflect.ValueOf(body).Elem())return nil}, nilcase reflect.Pointer:return func(ctx *gin.Context, structVale reflect.Value) error {v := fieldByIndexFromStructValue(structVale, field.Index, field.IsExported(), field.Type)if v.IsNil() {v.Set(reflect.New(v.Type().Elem()))}if err := ctx.ShouldBind(v.Interface()); err != nil {return NewParameterError(err.Error())}return nil}, nil// ... 其他类型处理default:return nil, unsupportedAttributeType(field.Name)}
}
代理机制核心代码
// 代理机制的核心实现 - 构建代理函数
func (p *proxy) buildProxyFn(x HandlerFunc, funcName string, last bool) gin.HandlerFunc {m := make(map[int]*bindStructFuncAndType)args, err := p.funcInjector.InjectFuncParameters(x,func(pt reflect.Type, i int, injected bool) any {switch pt {case ctxPointType, ctxType, goneContextPointType, goneContextType:return placeholder{Type: pt,}}p.injector.StartBindFuncs()return nil},func(pt reflect.Type, i int, injected bool) any {m[i] = &bindStructFuncAndType{Fn:   p.injector.BindFuncs(),Type: pt,}return nil},)// ... 错误处理fv := reflect.ValueOf(x)return func(context *gin.Context) {// ... 性能统计parameters := make([]reflect.Value, 0, len(args))for i, arg := range args {// ... 参数处理if f, ok := m[i]; ok {parameter, err := f.Fn(context, arg)if err != nil {p.responser.Failed(context, err)return}parameters = append(parameters, parameter)} else {parameters = append(parameters, arg)}}// 调用用户函数values := fv.Call(parameters)// 处理返回值var results []anyfor i := 0; i < len(values); i++ {// ... 返回值处理}p.responser.ProcessResults(context, context.Writer, last, funcName, results...)}
}

测试结果

BenchmarkProcessRequestWithInject-8   	  261738	      4124 ns/op
BenchmarkProcessRequestWithOriGin-8   	  370796	      3166 ns/op
BenchmarkProxyGinHandlerFunc-8        	  278386	      3942 ns/op
BenchmarkCallOriGinHandlerFunc-8      	  387363	      3016 ns/op

结果分析

  1. 完整请求处理性能

    • Gone-Gin: 4124 ns/op
    • 原生 Gin: 3166 ns/op
    • 性能差距: 约 30%
  2. 处理函数性能

    • Gone-Gin 代理: 3942 ns/op
    • 原生 Gin 函数: 3016 ns/op
    • 性能差距: 约 31%

从测试结果可以看出,Gone-Gin 相比原生 Gin 有一定的性能损耗,在同一个数量级上,这主要是由于以下原因:

  1. 反射机制:Gone-Gin 使用反射来实现参数注入和类型转换,这会带来一定的性能开销
  2. 代理层:Gone-Gin 增加了代理层来转换用户函数,增加了函数调用链的长度
  3. 额外功能:Gone-Gin 提供了更多的功能,如参数自动绑定、类型转换等,这些功能会带来额外的性能开销

优化建议

虽然 Gone-Gin 相比原生 Gin 有一定的性能损耗,但在大多数业务场景下,这种性能差距是可以接受的,因为它带来了更好的开发体验和更高的开发效率。如果需要进一步优化性能,可以考虑以下方面:

  1. 减少反射使用:尽可能减少反射的使用,或者使用缓存来减少反射的开销
  2. 优化代理层:简化代理层的实现,减少函数调用链的长度
  3. 按需加载:根据实际需求,只加载必要的功能,减少不必要的性能开销
  4. 使用更高效的数据结构:在处理大量请求时,使用更高效的数据结构来存储和处理数据

结论

Gone-Gin 通过提供更便捷的依赖注入和参数绑定功能,大大提高了开发效率,虽然相比原生 Gin 有一定的性能损耗,但在大多数业务场景下,这种性能差距是可以接受的。在选择使用 Gone-Gin 还是原生 Gin 时,需要根据实际业务需求和性能要求来权衡。

对于追求极致性能的场景,可以考虑使用原生 Gin;而对于注重开发效率和代码可维护性的场景,Gone-Gin 是一个更好的选择。

http://www.dtcms.com/wzjs/441929.html

相关文章:

  • 网站建设工作汇报新网站排名优化怎么做
  • 哪个网站做初中英语试题赚钱成年s8视频加密线路
  • 装修公司做自己网站北京百度快速优化排名
  • 做采集网站赚钱吗网页设计首页制作
  • 咨询网站设计广告类的网站
  • 四川建设网官网安全员证书查询杭州网站seo外包
  • 学网站开发要什么基础网络整合营销方案
  • 网站建设财务项目管理制度全球中文网站排名
  • 福州网站建设公司哪家好学编程的正规学校
  • 在哪里做卖车网站成都网络推广优化
  • 金融网站建设方案书在线培训系统
  • b站有推广吗wordpress建站
  • 代理网上注册公司粤语seo是什么意思
  • 哪里发布网站开发需求源码网
  • 只做一种产品的网站北京网站制作公司
  • 公司网页制作官网关键词优化上海
  • 做网站平台难在哪里近期国内新闻热点事件
  • 做网站备案是个人还是企业好新闻头条国内大事
  • 重庆智能模板建站如何做网站搜索引擎优化
  • 网站建设方案书是啥谷歌浏览器怎么下载
  • 免费b站视频推广网站2023邮件营销
  • 旅游网络营销策划方案强强seo博客
  • 17网站一起做网店打不开百度快照是什么意思
  • 网站推广广告 优帮云域名网站
  • 有没有专门做针织衫的网站公司网络营销推广方案
  • 郑州市建设厅官方网站网络营销的优缺点
  • 网站制作费用 政府采购it培训四个月骗局
  • 湖南营销型网站建设 真好磐石网络网站竞价推广托管公司
  • 做网站 源码百度域名提交收录网址
  • 图书网站建设实训心得产品营销策略怎么写