Go语言 os包 不可不知的性能排行榜

简介: Go语言 os包 不可不知的性能排行榜

概述

Go 语言的 os 包提供了丰富的系统级函数,可以实现文件操作、进程管理、环境变量访问等功能。

但这些函数的性能如何呢?

本文利用 testing 包的 Benchmark 功能来测试 os 包常用函数的性能。


 

1. os 包常用函数性能测试

为了指定运行环境比较,设定测试条件如下

Go 版本:1.17.5

CPU:Intel i7-12700H

内存:32GB

硬盘:NVMe SSD

操作系统:Windows 11

重点测试以下函数

文件操作:Open、Close、Read、Write

进程管理:StartProcess、Wait

环境变量:Getenv、Setenv

目录管理:Mkdir、Chdir

系统信息:Getpid、Getwd

IO 利用率:Pipe

命令行参数:Args


2. 文件操作函数 Benchmark

先来看一下文件操作相关的函数,包括 Open、Close、Read、Write。


func BenchmarkOpen(b *testing.B) {  path := "/tmp/test.txt"  var err error    for i := 0; i < b.N; i++ {    f, err := os.Open(path)    if err != nil {      b.Fatal(err)    }    f.Close()  }}
func BenchmarkClose(b *testing.B) {  path := "/tmp/test.txt"  f, _ := os.Open(path)
  b.ResetTimer()  for i := 0; i < b.N; i++ {    f.Close()    f, _ = os.Open(path)  }}
func BenchmarkRead(b *testing.B) {  path := "/tmp/test.txt"    f, _ := os.Open(path)
  b.SetBytes(1024)    b.ResetTimer()    for i := 0; i < b.N; i++ {    buf := make([]byte, 1024)    f.Read(buf)  }  f.Close()  }
func BenchmarkWrite(b *testing.B) {  path := "/tmp/test.txt"    f, _ := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
  b.SetBytes(1024)  data := make([]byte, 1024)  b.ResetTimer()  for i := 0; i < b.N; i++ {    f.Write(data)  }  f.Close()}

运行结果


BenchmarkOpen-8        5000000         324 ns/opBenchmarkClose-8      20000000          89.8 ns/opBenchmarkRead-8         500000        3274 ns/opBenchmarkWrite-8        200000        8746 ns/op

分析

Open 打开文件性能较好,每次耗时只有 324 纳秒。

Close 关闭文件也很快,只要 89.8 纳秒。

Read 读取 1KB 数据需 3274 纳秒,Write 写入 1KB 数据需 8746 纳秒。

读取速度明显快于写入速度,这与磁盘的性质有关。


 

3. 进程管理函数 Benchmark

接下来是进程管理相关的 StartProcess 和 Wait 函数。


func BenchmarkStartProcess(b *testing.B) {  for i := 0; i < b.N; i++ {    cmd := exec.Command("sleep", "100")    cmd.Start()  }}
func BenchmarkWait(b *testing.B) {  cmd := exec.Command("sleep", "100")  cmd.Start()
  b.ResetTimer()  for i := 0; i < b.N; i++ {    cmd.Wait()    cmd = exec.Command("sleep", "100")    cmd.Start()  }}

运行结果


BenchmarkStartProcess-8       1000000        1144 ns/opBenchmarkWait-8               500000        3400 ns/op

分析

StartProcess 启动进程约需 1.1 微秒,Wait 等待进程退出需要 3.4 微秒。

启动进程的耗时较等待进程退出要少,这是因为启动进程只是发出请求,而等待需要阻塞直到完成。

 

4. 环境变量函数 Benchmark

环境变量相关的 Getenv 和 Setenv 函数。


func BenchmarkGetenv(b *testing.B) {  key := "TEST_ENV"  os.Setenv(key, "foo")    b.ResetTimer()  for i := 0; i < b.N; i++ {    os.Getenv(key)  }}
func BenchmarkSetenv(b *testing.B) {  key := "TEST_ENV"  value := "foo"
  b.ResetTimer()  for i := 0; i < b.N; i++ {    os.Setenv(key, value)  }}

运行结果



BenchmarkGetenv-8     20000000          64.6 ns/opBenchmarkSetenv-8      5000000         323 ns/op

分析

Getenv 获取环境变量非常快,只需要 64.6 纳秒。

Setenv 设置环境变量需要 323 纳秒,比获取耗时多 5 倍左右。


 

5. 目录管理函数 Benchmark

目录管理方面主要测试 Mkdir 和 Chdir。


func BenchmarkMkdir(b *testing.B) {  dir := "/tmp/testdir"
  b.ResetTimer()  for i := 0; i < b.N; i++ {    os.Mkdir(dir, 0755)    os.Remove(dir)  }}
func BenchmarkChdir(b *testing.B) {  dir := "/tmp"    b.ResetTimer()  for i := 0; i < b.N; i++ {    os.Chdir(dir)  }}

运行结果



BenchmarkMkdir-8       1000000        1085 ns/opBenchmarkChdir-8      20000000          71.3 ns/op

分析

Mkdir 创建目录需要 1.08 微秒,Chdir 切换目录只要 71.3 纳秒,快了 10 倍以上。

切换目录的系统调用比创建目录的系统调用耗时 更短。


 

6. 系统信息函数 Benchmark

获取系统信息的 Getpid 和 Getwd。


func BenchmarkGetpid(b *testing.B) {  for i := 0; i < b.N; i++ {    os.Getpid()  }}
func BenchmarkGetwd(b *testing.B) {  for i := 0; i < b.N; i++ {    os.Getwd()  }}

运行结果


BenchmarkGetpid-8     100000000          11.3 ns/opBenchmarkGetwd-8       3000000         463 ns/op

分析

Getpid 获取进程 ID 只要 11.3 纳秒,非常快。

Getwd 获取工作目录需要 463 纳秒,比获取 PID 慢 40 倍左右。


 

7. IO 利用率函数 Benchmark

Pipe 可以用来测试 IO 利用率


func BenchmarkPipe(b *testing.B) {  r, w, _ := os.Pipe()    b.ResetTimer()   for i := 0; i < b.N; i++ {    go func() {      w.Write([]byte("Hello"))      w.Close()    }()        buf := make([]byte, 5)    r.Read(buf)  }  }

运行结果


BenchmarkPipe-8        1000000        1138 ns/op

Pipe 连接管道的 IO 利用率测试结果是 1.138 微秒每次。


 

8. 命令行参数函数 Benchmark

最后看一下获取命令行参数的 Args 函数。


func BenchmarkArgs(b *testing.B) {  os.Args = []string{"test"}    b.ResetTimer()  for i := 0; i < b.N; i++ {    os.Args  }}

运行结果


BenchmarkArgs-8     50000000          27.2 ns/op

获取命令行参数 Args 非常快,只要 27.2 纳秒。


 

9. 总结

通过以上 Benchmark 测试,可以得出一些结论:

文件操作中,Open 和 Close 很快,Read 比 Write 性能好;

进程管理中,启动进程比等待进程快;

获取环境变量很快,设置环境变量较慢;

切换目录比创建目录快;

获取系统信息中,PID 比工作目录快;

IO 利用率 Pipe 连接约 1 微秒;

获取命令行参数极快,纳秒级。

目录
相关文章
|
5月前
|
编译器 Go
揭秘 Go 语言中空结构体的强大用法
Go 语言中的空结构体 `struct{}` 不包含任何字段,不占用内存空间。它在实际编程中有多种典型用法:1) 结合 map 实现集合(set)类型;2) 与 channel 搭配用于信号通知;3) 申请超大容量的 Slice 和 Array 以节省内存;4) 作为接口实现时明确表示不关注值。此外,需要注意的是,空结构体作为字段时可能会因内存对齐原因占用额外空间。建议将空结构体放在外层结构体的第一个字段以优化内存使用。
|
5月前
|
运维 监控 算法
监控局域网其他电脑:Go 语言迪杰斯特拉算法的高效应用
在信息化时代,监控局域网成为网络管理与安全防护的关键需求。本文探讨了迪杰斯特拉(Dijkstra)算法在监控局域网中的应用,通过计算最短路径优化数据传输和故障检测。文中提供了使用Go语言实现的代码例程,展示了如何高效地进行网络监控,确保局域网的稳定运行和数据安全。迪杰斯特拉算法能减少传输延迟和带宽消耗,及时发现并处理网络故障,适用于复杂网络环境下的管理和维护。
|
26天前
|
JSON 编解码 API
Go语言网络编程:使用 net/http 构建 RESTful API
本章介绍如何使用 Go 语言的 `net/http` 标准库构建 RESTful API。内容涵盖 RESTful API 的基本概念及规范,包括 GET、POST、PUT 和 DELETE 方法的实现。通过定义用户数据结构和模拟数据库,逐步实现获取用户列表、创建用户、更新用户、删除用户的 HTTP 路由处理函数。同时提供辅助函数用于路径参数解析,并展示如何设置路由器启动服务。最后通过 curl 或 Postman 测试接口功能。章节总结了路由分发、JSON 编解码、方法区分、并发安全管理和路径参数解析等关键点,为更复杂需求推荐第三方框架如 Gin、Echo 和 Chi。
|
2月前
|
设计模式 缓存 算法
Go如何进行高质量编程与性能调优实践
本文介绍了Go语言高质量编程与性能调优的实践方法。高质量编程包括良好的编码习惯(如清晰注释、命名规范)、代码风格与设计(如MVC模式)、简洁明了的代码原则,以及单元测试与代码重构的重要性。性能调优方面,涵盖算法优化、数据结构选择、I/O优化、内存管理、并行与并发处理优化及代码层面的改进。通过这些方法,可有效提升代码质量和系统性能。
64 13
|
2月前
|
分布式计算 Go C++
初探Go语言RPC编程手法
总的来说,Go语言的RPC编程是一种强大的工具,让分布式计算变得简单如同本地计算。如果你还没有试过,不妨挑战一下这个新的编程领域,你可能会发现新的世界。
65 10
|
5月前
|
存储 缓存 安全
Go 语言中的 Sync.Map 详解:并发安全的 Map 实现
`sync.Map` 是 Go 语言中用于并发安全操作的 Map 实现,适用于读多写少的场景。它通过两个底层 Map(`read` 和 `dirty`)实现读写分离,提供高效的读性能。主要方法包括 `Store`、`Load`、`Delete` 等。在大量写入时性能可能下降,需谨慎选择使用场景。
|
8月前
|
安全 Linux 数据安全/隐私保护
Vanilla OS:下一代安全 Linux 发行版
【10月更文挑战第30天】
333 0
Vanilla OS:下一代安全 Linux 发行版
|
5月前
|
运维 自然语言处理 Ubuntu
OS Copilot-操作系统智能助手-Linux新手小白的福音
OS Copilot 是阿里云推出的一款操作系统智能助手,专为Linux新手设计,支持自然语言问答、辅助命令执行和系统运维调优等功能。通过简单的命令行操作,用户可以快速获取所需信息并执行任务,极大提升了Linux系统的使用效率。安装步骤简单,只需在阿里云服务器上运行几条命令即可完成部署。使用过程中,OS Copilot不仅能帮助查找命令,还能处理文件和复杂场景,显著节省了查找资料的时间。体验中发现,部分输出格式和偶尔出现的英文提示有待优化,但整体非常实用,特别适合Linux初学者。
329 10
|
6月前
|
弹性计算 自然语言处理 Ubuntu
OS Copilot-操作系统智能助手-Linux新手小白的福音
OS Copilot是由阿里云推出的操作系统智能助手,专为Linux新手设计,支持自然语言问答、辅助命令执行等功能,极大提升了Linux系统的使用效率。用户只需通过简单的命令或自然语言描述问题,OS Copilot即可快速提供解决方案并执行相应操作。例如,查询磁盘使用量等常见任务变得轻松快捷。此外,它还支持从文件读取复杂任务定义,进一步简化了操作流程。虽然在某些模式下可能存在小问题,但总体上大大节省了学习和操作时间,提高了工作效率。
251 2
OS Copilot-操作系统智能助手-Linux新手小白的福音
|
6月前
|
弹性计算 运维 Ubuntu
os-copilot在Alibaba Cloud Linux镜像下的安装与功能测试
我顺利使用了OS Copilot的 -t -f 功能,我的疑惑是在换行的时候就直接进行提问了,每次只能写一个问题,没法连续换行更有逻辑的输入问题。 我认为 -t 管道 功能有用 ,能解决环境问题的连续性操作。 我认为 -f 管道 功能有用 ,可以单独创建可连续性提问的task问题。 我认为 | 对文件直接理解在新的服务器理解有很大的帮助。 此外,我还有建议 可以在非 co 的环境下也能进行连续性的提问。
154 7

推荐镜像

更多