提升读写性能,go语言的bufio包

最近在尝试学习go语言,想去洛谷做几道题吧,结果前几个答案是正确的,最后两个报了超时,标准输入输出fmt存在读写性能上的缺陷。deepseek推荐了这个bufio包。

bufio 包的核心功能

bufio 提供缓冲 I/O,通过减少系统调用来提升读写性能。

类型用途
bufio.Reader带缓冲的读取器
bufio.Writer带缓冲的写入器
bufio.Scanner按 token(行/单词等)扫描的便捷工具
bufio.ReadWriterReader + Writer 的组合

Scanner 的默认行为

默认缓冲区大小 = 64KB (bufio.MaxScanTokenSize)
默认分割函数 = ScanLines(按换行符分割)

Buffer 方法

  • buf:提供外部缓冲区(避免内部小缓冲区频繁扩容)
  • max:允许的最大 token 长度(必须 >= 16 且通常 >= len(buf))
scanner.Buffer(buf []byte, max int)

分割逻辑

scanner.Split(bufio.ScanWords) 的作用是改变 Scanner 的分割逻辑,从默认的按行分割改为按单词分割。

函数分割规则token 示例
ScanLines (默认)按换行符 \n,自动去掉换行"第一行", "第二行"
ScanWords按 Unicode 字母数字边界,空格/标点分隔"Hello", "world,"(逗号保留)
ScanRunes按 UTF-8 字符分割'H', 'e', '你', '好'
ScanBytes按字节分割byte(72), byte(101)

P1170 兔八哥与猎人实战

仅使用fmt包的情况下,最后的两个测试点会因超时而无法通过。

package main

import (
    "bufio"
    "fmt"
    "os"
    "strconv"
)

var scanner *bufio.Scanner

func init() {
    scanner = bufio.NewScanner(os.Stdin)
    scanner.Buffer(make([]byte, 1024*1024), 1024*1024)
    scanner.Split(bufio.ScanWords)
}

func nextInt() int {
    scanner.Scan()
    num, _ := strconv.Atoi(scanner.Text())
    return num
}

func Abs(x int) int {
    if x < 0 {
        return -x
    }
    return x
}

func Gcd(x, y int) int {
    if y == 0 {
        return x
    }
    return Gcd(y, x%y)
}

func main() {
    n := nextInt()
    for i := 1; i <= n; i++ {
        hx := nextInt()
        hy := nextInt()
        rx := nextInt()
        ry := nextInt()
        res := Gcd(Abs(hx-rx), Abs(hy-ry))
        if res == 1 {
            fmt.Println("no")
        } else {
            fmt.Println("yes")
        }
    }
}

性能注意事项

分割方式性能适用场景
ScanLines最快日志文件、配置文件(每行独立)
ScanWords较快文本分析、词频统计
ScanRunes中等处理 Unicode 文本、字符级操作
ScanBytes最快二进制数据处理

标签: go语言

移动端可扫我直达哦~

推荐阅读

thumbnail 2026-06-04

go语言gin框架的学习笔记

上半年尝试制作了一个微信小程序,通过小程序请求后台服务器,服务器负责组装好用户需求的mp3文件,然后返回给用户播放地址,以实现一个简单的听写功能。其中后台的逻辑基本都是通过deepseek实现的,虽然成功跑通了,但是一直想从头手搓一遍...

少儿编程 go语言

thumbnail 2026-05-30

fmt,Go 语言自带的格式化输入输出包

fmt 可以理解为 Format(格式)的缩写——因为它擅长格式化数据(比如把数字嵌进句子中间)。fmt 就是 Go 语言的"终端对话工具",让你能在屏幕上显示东西,也能从键盘获取输入。fmt包的常用指令 概念对应 fmt 函数标准输...

少儿编程 go语言

thumbnail 2026-05-27

乱点技能树之-go语言笔记篇

系统仍旧是廉颇老矣的windows7,所以很多软件的新版本都没法运行,就像go已经出到了1.26版本,但win7上仅支持1.20.14,再往上就不受支持了,所以下方的代表仅在上述版本中验证通过。学习go语言的第一感受是,go语言取消了...

少儿编程 go语言