基准测试的缓冲写入
writingBU.go
程序使用随机生成的数据来产生虚拟文件。这个程序的变量是缓冲的大小和输出文件的大小。
writingBU.go
的第一部分如下:
writingBU.go
的第二段代码如下:
func createBuffer(buf *[]byte, count int) {
*buf = make([]byte, count)
if count == 0 {
return
}
for i := 0; i < count; i++ {
intByte := byte(random(0, 100))
if len(*buf) > count {
return
}
*buf = append(*buf, intByte)
}
}
writingBU.go
的第三部分如下:
func Create(dst string, b, f int) error {
_, err := os.Stat(dst)
if err == nil {
return fmt.Error("File %s already exists.", dst)
}
destination, err := os.Create(dst)
if err != nil {
return err
}
defer destination.Close()
panic(err)
}
buf := make([]byte, 0)
for {
buf = buf[:b]
if _, err := destination.Write(buf); err != nil {
return err
}
if f < 0 {
break
}
f = f - len(buf)
}
return err
}
程序中的 Create()
函数做了所有工作,他是需要进行基准测试的函数。
注意如果缓冲大小和文件大小不是 Create()
函数的签名的一部分,在给 Create()
函数写基准测试函数时您将遇到问题,因为您需要使用 BUFFERSIZE
和 FILESIZE
全局变量,它们都是在 writingBU.go
的 main()
函数中初始化的。
这将是一个难点在 writingBU_test.go
文件中。这意味着为了给一个函数创建一个基准测试,您应该在您写代码时就考虑这个问题。
writingBU.go
的其余代码如下:
err = os.Remove(output)
if err != nil {
fmt.Println(err)
}
}
尽管在 main()
函数里调用 os.Remove()
删除了临时文件,但没有在基准测试函数中调用它,在基准测试函数中调用它比较简单,所以这不是问题。
在一台有 SSD 硬盘的 macOS High Sierra 机器上执行 writingBU.go
俩次,用 time(1)
工具来检测程序产生如下输出但速度:
$ time go run writingBU.go 1 100000
real 0m1.193s
sys 0m0.809s
$ time go run writingBU.go 10 100000
real 0m0.283s
user 0m0.195s
sys 0m0.228s
尽管这显示出写缓冲的大小对程序的性能起到关键作用,但我们需要更具体更准确。因此,我们来写基准测试函数存储为 writingBU_test.go
。
writingBU_test.go
的第一部分如下:
您会记得这不是一个有效的基准测试函数。
writingBU_test.go
的第二段代码如下:
func Benchmark1Create(b *testing.B) {
benchmarkCreate(b, 1, 1000000)
}
func Benchmark2Create(b *testing.B) {
benchmarkCreate(b, 2, 1000000)
}
func Benchmark4Create(b *testing.B) {
benchmarkCreate(b, 4, 1000000)
}
func Benchmark10Create(b *testing.B) {
benchmarkCreate(b, 10, 1000000)
}
func Benchmark1000Create(b *testing.B) {
benchmarkCreate(b, 1000, 1000000)
}
这里我们写了五个基准测试函数来检测 benchmarkCreate()
函数的性能,它用写缓冲大小变量检测 Create()
函数的性能。
对 writingBU.go
和 writingBU_test.go
文件执行 go test
将产生如下输出:
下面的输出也检测了基准测试函数的内存分配:
现在来解释一下这俩个 命令的输出。
很明显使用一个大小为 1 个字节的写缓冲是完全无效的并且缓冲所有的操作。另外,这样的缓冲大小需要更多的内存操作,这也使程序运行的更慢!
当决定用 10 个字节的写缓冲时,这会变的更快。最后,这个结果显示使用 1,000 字节的写缓冲没有比使用 10 字节的快 100 倍,这意味着在速度和写缓冲大小之间的最佳点是在这俩个值之间。