郑文峰的博客 郑文峰的博客
首页
  • Go语言高性能编程
分类
标签
归档
关于
  • 导航 (opens new window)
  • 代码片段 (opens new window)
  • 收藏
  • 友链
  • 外部页面

    • 开往 (opens new window)
GitHub (opens new window)

zhengwenfeng

穷则变,变则通,通则久
首页
  • Go语言高性能编程
分类
标签
归档
关于
  • 导航 (opens new window)
  • 代码片段 (opens new window)
  • 收藏
  • 友链
  • 外部页面

    • 开往 (opens new window)
GitHub (opens new window)
  • python

  • go语言

    • go简单使用grpc
    • gin中validator模块的源码分析
    • 优化gin表单的错误提示信息
    • go中如何处理error
    • tcp缓存引起的日志丢失
    • 使用etcd分布式锁导致的协程泄露与死锁问题
    • go语言高性能编程

      • Go协程池深度解析:原理、实现与最佳实践
      • Go语言Interface Boxing原理与性能优化指南
      • Go语言遍历性能深度解析:从原理到优化实践
      • Go语言零拷贝技术完全指南
      • Go语言不可变数据共享:无锁并发编程实践
      • Go语言内存预分配完全指南
      • Go语言原子操作完全指南
      • Go语言堆栈分配与逃逸分析深度解析
      • Go语言空结构体:零内存消耗的高效编程
      • Go语言结构体内存对齐完全指南
      • Go语言字符串拼接性能对比与优化指南
      • Go语言延迟初始化(Lazy Initialization)最佳实践
      • Go语言高效IO缓冲技术详解
        • 1. 简介
        • 2. 不带缓冲的写入
        • 3. 带缓冲的写入
        • 4. 控制缓冲区容量
        • 5. 带缓冲与不带缓冲的 Benchmark
        • 6. 总结
  • linux

  • 其他

  • 编程
  • go语言
  • go语言高性能编程
zhengwenfeng
2025-06-14
目录

Go语言高效IO缓冲技术详解

# 1. 简介

在计算机系统中,I/O操作(如文件读写、网络通信)是性能瓶颈的主要来源之一。主要原因包括:

  1. 系统调用开销:每次直接I/O操作都涉及用户态和内核态的上下文切换
  2. 硬件限制:磁盘和网络设备更适合大块数据传输
  3. 频繁小数据操作:大量小数据写入会显著降低性能

缓冲技术通过在内存中聚合数据,减少实际I/O操作次数,可显著提升性能。

# 2. 不带缓冲的写入

直接频繁调用系统API,性能最差:

// 每次写入都触发系统调用
f, _ := os.Create("output.txt")
defer f.Close()

for i := 0; i < 10000; i++ {
    f.Write([]byte("line\n"))  // 高成本操作
}
1
2
3
4
5
6
7

# 3. 带缓冲的写入

使用bufio.Writer自动缓冲:

f, _ := os.Create("output.txt")
defer f.Close()

buf := bufio.NewWriter(f)  // 默认4KB缓冲
for i := 0; i < 10000; i++ {
    buf.WriteString("line\n")  // 内存操作
}
buf.Flush()  // 最终写入磁盘
1
2
3
4
5
6
7
8

# 4. 控制缓冲区容量

根据场景调整缓冲区大小:

f, _ := os.Create("output.txt")
defer f.Close()

// 16KB缓冲,适合大文件写入
buf := bufio.NewWriterSize(f, 16*1024)  
1
2
3
4
5

# 5. 带缓冲与不带缓冲的 Benchmark

比较通过直接调用os.File.Write相比,使用bufio.Writer向磁盘写入一百万行数据。

package perf

import (
    "bufio"
    "io"
    "os"
    "strconv"
    "sync"
    "testing"
)

type Data struct {
    Value []byte
}

var dataPool = sync.Pool{
    New: func() any {
        return &Data{Value: make([]byte, 0, 32)}
    },
}

const N = 10000

func writeNotBuffered(w io.Writer, count int) {
    for i := 0; i < count; i++ {
        d := dataPool.Get().(*Data)
        d.Value = strconv.AppendInt(d.Value[:0], int64(i), 10)
        w.Write(d.Value)
        w.Write([]byte(":val\n"))
        dataPool.Put(d)
    }
}

func writeBuffered(w io.Writer, count int) {
    buf := bufio.NewWriterSize(w, 16*1024)
    for i := 0; i < count; i++ {
        d := dataPool.Get().(*Data)
        d.Value = strconv.AppendInt(d.Value[:0], int64(i), 10)
        buf.Write(d.Value)
        buf.Write([]byte(":val\n"))
        dataPool.Put(d)
    }
    buf.Flush()
}

func BenchmarkWriteNotBuffered(b *testing.B) {
    for b.Loop() {
        f, _ := os.CreateTemp("", "nobuf")
        writeNotBuffered(f, N)
        f.Close()
        os.Remove(f.Name())
    }
}

func BenchmarkWriteBuffered(b *testing.B) {
    for b.Loop() {
        f, _ := os.CreateTemp("", "buf")
        writeBuffered(f, N)
        f.Close()
        os.Remove(f.Name())
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

运行结果如下,带缓冲的性能提升了约 62 倍,但内存申请多了 30%。

$ go test -bench=. -benchmem .  
goos: darwin
goarch: arm64
pkg: main/demo
cpu: Apple M4 Pro
BenchmarkWriteNotBuffered-12                  64          18470001 ns/op           53758 B/op      10007 allocs/op
BenchmarkWriteBuffered-12                   3984            297904 ns/op           70122 B/op      10008 allocs/op
PASS
ok      main/demo       3.530s
1
2
3
4
5
6
7
8
9

# 6. 总结

应用场景

  1. 频繁的执行小数据量的 I/O。
  2. 减少系统调用。
  3. 高吞吐量比延迟更重要。

不适用场景

  1. 实时性要求高。
  2. 过度缓冲导致内存使用不受控制。
#go语言#go语言高性能编程
上次更新: 2025/06/14, 16:16:07
Go语言延迟初始化(Lazy Initialization)最佳实践
快速了解iptables

← Go语言延迟初始化(Lazy Initialization)最佳实践 快速了解iptables→

最近更新
01
Go语言延迟初始化(Lazy Initialization)最佳实践
06-14
02
Go语言字符串拼接性能对比与优化指南
06-14
03
Go语言结构体内存对齐完全指南
06-14
更多文章>
Theme by Vdoing | Copyright © 2022-2025 zhengwenfeng | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式