golang程序性能提升改进篇之文件的读写---第一篇

背景:接手的项目是golang开发的(本人初次接触golang)经常出现oom。这个程序是计算和io密集型,调用流量属于明显有波峰波谷,但是因为各种原因,当前无法快速通过serverless或者动态在高峰时段调整资源,低峰释放资源的方式进行解决,因此只能通过分析内存和cpu消耗热点,然后改动代码,进而解决服务的稳定性和性能问题。

思路
通过搜索了解golang程序如何进行性能分析,当时就是使用pprof了,通过分析发现了程序有一些使用内存较多的地方,例如我们读取大量文件,通过分析发现io.ioutil.ReadAll消耗内存较多,通过查询发现io.copy可以减少一些内存消耗。

在这里插入图片描述

同时也在网上发现其他开源项目与我们遇到的情况类似。 https://github.com/elastic/beats/issues/36151是某个开源软件中将ioutil.ReadAll 更新为io.Copy的讨论,里面也有他们的对比测试 。

性能对比测试:

在本机上写了一段代码,ioutil.ReadAll和io.Copy的go benchmarktest结果如下
在这里插入图片描述

代码比较简单 main.go

package main

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"time"
)

func fetchWithReadAll(url string) ([]byte, time.Duration, error) {
	// 发起HTTP GET请求
	resp, err := http.Get(url)
	if err != nil {
		return nil, 0, err
	}
	defer resp.Body.Close()

	// 使用 io.ReadAll 读取响应内容
	start := time.Now()
	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, 0, err
	}
	duration := time.Since(start)
	return data, duration, nil
}

func fetchWithCopy(url string) ([]byte, time.Duration, error) {
	// 发起HTTP GET请求
	resp, err := http.Get(url)
	if err != nil {
		return nil, 0, err
	}
	defer resp.Body.Close()

	// 使用 io.Copy 读取响应内容
	start := time.Now()
	var buffer bytes.Buffer
	_, err = io.Copy(&buffer, resp.Body)
	if err != nil {
		return nil, 0, err
	}
	duration := time.Since(start)
	return buffer.Bytes(), duration, nil
}

func main() {
    //  此url能下载一个大约1-2mb的文本文件
	url := "http://x.y.z/abc.txt"

	// 测试 ioutil.ReadAll
	dataReadAll, durationReadAll, err := fetchWithReadAll(url)
	if err != nil {
		fmt.Printf("Error fetching with ReadAll: %v\n", err)
		return
	}
	fmt.Printf("ReadAll took %v for %d bytes\n", durationReadAll, len(dataReadAll))

	// 测试 io.Copy
	dataCopy, durationCopy, err := fetchWithCopy(url)
	if err != nil {
		fmt.Printf("Error fetching with Copy: %v\n", err)
		return
	}
	fmt.Printf("Copy took %v for %d bytes\n", durationCopy, len(dataCopy))
}

main_test.go

package main

import (
	"testing"
)

// 假设我们已有 fetchWithReadAll 和 fetchWithCopy 函数定义

// BenchmarkFetchWithReadAll 为 fetchWithReadAll 函数编写基准测试。
func BenchmarkFetchWithReadAll(b *testing.B) {
	//  此url能下载一个大约1-2mb的文本文件
	url := "http://x.y.z/abc.txt
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		_, _, err := fetchWithReadAll(url)
		if err != nil {
			b.Error(err)
		}
	}
}

// BenchmarkFetchWithCopy 为 fetchWithCopy 函数编写基准测试。
func BenchmarkFetchWithCopy(b *testing.B) {
	//  此url能下载一个大约1-2mb的文本文件
	url := "http://x.y.z/abc.txt"
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		_, _, err := fetchWithCopy(url)
		if err != nil {
			b.Error(err)
		}
	}
}

最后执行
···
go test -bench=.

···

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/798539.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

持续学习的综述: 理论、方法与应用(三:泛化分析)

前文连接&#xff1a;持续学习的综述: 理论、方法与应用&#xff08;一&#xff09; 前文连接&#xff1a;持续学习的综述: 理论、方法与应用&#xff08;二&#xff1a;理论基础&#xff09; 泛化分析 目前持续学习的理论研究主要是在增量任务的训练集上进行的&#xff0c;假…

QT VTK 简单测试工程

目录 1 目录结构 2 文件源码 3 运行结果 4 报错及处理 使用编译好的VTK库进行测试 1 目录结构 2 文件源码 Pro文件 QT core guigreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c17# You can make your code fail to compile if it uses deprecated APIs. #…

STM32-寄存器点灯案例详解

本文以PA1引脚点亮LED灯为案例&#xff0c;解析了STM32寄存器操作的配置过程&#xff0c;以及从手册查询方法和寄存器配置步骤。 一、概念 1.十六进制和二进制之间相互转换关系 首先&#xff0c;需要了解十六进制和二进制之间的基本转换方法。十六进制是一种基数为16的数制&…

《战甲神兵》开发者报告:游戏崩溃问题80%发生在Intel可超频酷睿i9处理器上——酷睿i7 K系列CPU也表现出高崩溃率

在Intel持续面临第13代和第14代CPU崩溃问题的背景下&#xff0c;近日&#xff0c;《战甲神兵》(Warframe)的开发者们于7月9日披露了游戏崩溃的统计数据&#xff0c;并描述了诊断该问题的过程。根据开发团队的说法&#xff0c;一名未进行超频且使用全新PC的员工&#xff0c;即便…

FOC(笔记二)

接上篇文章&#xff1a;FOC算法(笔记一)_马鞍波和三角波调制合成-CSDN博客 前面已经对FOC的开环控制进行了介绍&#xff0c;下面对FOC的闭环控制进行介绍。 本次使用的电机参数如下图所示&#xff1a; 一、HALL传感器 1.1、霍尔传感器的角度、速度计算 因为本次使用的是120安…

2024安全行业大模型技术应用态势发展报告

以上是资料简介和目录&#xff0c;如需下载&#xff0c;请前往星球获取&#xff1a;https://t.zsxq.com/dH9bu

蒙特卡洛抽样方法

目录 认识该方法 认识该方法 不断抽样逐渐逼近 计算Π 打点&#xff0c;落在圆&#xff08;1/4&#xff09;的概率 抽样点越多&#xff0c;Π的值越准确 蒙特卡洛不在于精确&#xff0c;也不在于找到最准确的数值。如下图所示&#xff0c;Π就等于红

Git代码管理工具 — 3 Git基本操作指令详解

目录 1 获取本地仓库 2 基础操作指令 2.1 基础操作指令框架 2.2 git status查看修改的状态 2.3 git add添加工作区到暂存区 2.4 提交暂存区到本地仓库 2.5 git log查看提交日志 2.6 git reflog查看已经删除的记录 2.7 git reset版本回退 2.8 添加文件至忽略列表 1 获…

006-三台交换机堆叠

三台交换机堆叠 链形连接和环形连接 链形配置IRF与环形配置IRF的区别 三个交换机链形配置IRF与三个交换机环形配置IRF的主要区别体现在以下几个方面&#xff1a; 物理位置要求&#xff1a; 链形连接&#xff1a;对成员设备的物理位置要求相对较低&#xff0c;主要适用于成员…

鸿蒙语言基础类库:【@system.app (应用上下文)】

应用上下文 说明&#xff1a; 从API Version 7 开始&#xff0c;该接口不再维护&#xff0c;推荐使用新接口。本模块首批接口从API version 3开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import app from system.app;app.getInfo …

Scrapy框架实现数据采集的详细步骤

需求描述&#xff1a; 本项目目标是使用Scrapy框架从宁波大学经济学院网站&#xff08;nbufe.edu.cn&#xff09;爬取新闻或公告详情页的内容。具体需求如下&#xff1a; 1、通过遍历多个页面&#xff08;共55页&#xff09;构建翻页URL。 2、使用scrapy自带的xpath从每页的…

C++基础(二十):常见C++11的新特性

1979年&#xff0c;贝尔实验室的本贾尼等人试图分析unix内核的时候&#xff0c;试图将内核模块化&#xff0c;于是在C 语言的基础上进行扩展&#xff0c;增加了类的机制&#xff0c;完成了一个可以运行的预处理程序&#xff0c;称之为C with classes。语言的发展就像是练功打怪…

项目三层架构详情

三层架构 三层架构就是为了符合“高内聚&#xff0c;低耦合”思想&#xff0c;把各个功能模块划分为表示层&#xff08;UI&#xff09;、业务逻辑层&#xff08;BLL&#xff09;和数据访问层&#xff08;DAL&#xff09;三层架构&#xff0c;各层之间采用接口相互访问&#xf…

UDP网络通信(发送端+接收端)实例 —— Python

简介 在网络通信编程中&#xff0c;用的最多的就是UDP和TCP通信了&#xff0c;原理这里就不分析了&#xff0c;网上介绍也很多&#xff0c;这里简单列举一下各自的优缺点和使用场景 通信方式优点缺点适用场景UDP及时性好&#xff0c;快速视网络情况&#xff0c;存在丢包 与嵌入…

Windows终端远程登陆Linux服务器(SSH+VScode)

W i n d o w s 终端远程登陆 L i n u x 服务器&#xff08; S S H V S c o d e &#xff09; \huge{Windows终端远程登陆Linux服务器&#xff08;SSHVScode&#xff09;} Windows终端远程登陆Linux服务器&#xff08;SSHVScode&#xff09; 文章目录 写在前面通过SSH远程连接L…

Postman下载及使用说明

Postman使用说明 Postman是什么&#xff1f; ​ Postman是一款接口对接工具【接口测试工具】 接口&#xff08;前端接口&#xff09;是什么&#xff1f; ​ 前端发送的请求普遍被称为接口 ​ 通常有网页的uri参数格式json/key-value请求方式post/get响应请求的格式json 接…

@google/model-viewer 导入 改纹理 (http-serve)

导入模型 改纹理 效果图 <template><div><h1>鞋模型</h1><model-viewerstyle"width: 300px; height: 300px"id"my-replace-people"src"/imgApi/Astronaut.glb"auto-rotatecamera-controls></model-viewer>&…

网络分层及通信过程

网络分层体系 主流的理论体系中主要包含三种网络分层模型&#xff0c;即ISO的七层网络模型、TCP/IP的四层网络模型以及结合两种模型优点的五层网络模型&#xff0c;关于网络模型&#xff0c;主要起到对网络体系的一个整体认识&#xff0c;作为网络知识学习的开始&#xff0c;这…

【Python进阶】正则表达式、pymysql模块

目录 一、正则表达式的概述 1、基本介绍 2、快速使用re模块 二、正则的常见规则 1、匹配单个字符 2、原始字符串 3、匹配多个字符 4、匹配开头和结尾 5、匹配分组 三、Python与MySQL交互 1、pymysql模块的安装 2、pymysql的操作步骤 3、connection对象 4、cursor…

【Git从入门到精通】——Git常用命令总结

&#x1f3bc;个人主页&#xff1a;【Y小夜】 &#x1f60e;作者简介&#xff1a;一位双非学校的大二学生&#xff0c;编程爱好者&#xff0c; 专注于基础和实战分享&#xff0c;欢迎私信咨询&#xff01; &#x1f386;入门专栏&#xff1a;&#x1f387;【MySQL&#xff0…