分享
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。
我用50亿字节的内存写入操作测试了`go`和`rust`的性能,发现`go`的内存操作比`rust`快!
我并不是一次性分配50亿字节内存,而是每次调用函数写入100000(大约100K不到一点)字节,反复调用5万次。我测试了两种写入方式,一种是初始化预分配内存的,另一种是初始化不分配内存的。结果是预分配模式下,`go`大大领先`rust`,速度达到`rust`的1.78倍;不预先分配内存模式下,双方性能相当。
`go`源代码(`app.go`和`app_test.go`)
```
//app.go
package main
import (
"fmt"
"time"
)
const L = 100000
const N = 50000
//预分配内存模式
func preAppend() []byte {
buf := make([]byte, 0, L)
for i := 0; i < L; i++ {
buf = append(buf, 's')
}
return buf
}
//不分配内存模式
func normalAppend() []byte {
buf := make([]byte, 0)
for i := 0; i < L; i++ {
buf = append(buf, 's')
}
return buf
}
func main() {
start := time.Now()
for i := 0; i < N; i++ {
preAppend()
}
fmt.Printf("preAppend Time:%v\n", time.Now().Sub(start).Seconds())
start = time.Now()
for i := 0; i < N; i++ {
normalAppend()
}
fmt.Printf("normalAppend Time:%v\n", time.Now().Sub(start).Seconds())
}
//app_test.go
package main
import (
"testing"
)
func TestNormalAppend(t *testing.T) {
for i := 0; i < N; i++ {
normalAppend()
}
println("TestNormalAppend")
}
func TestPreAppend(t *testing.T) {
for i := 0; i < N; i++ {
preAppend()
}
println("TestPreAppend")
}
```
`rust`源代码:
```
//main.rs
use std::time;
const N: isize = 50000;
const L: usize = 100000;
fn main() {
let start = time::SystemTime::now();
for _i in 0..N {
pre_append();
}
let end = time::SystemTime::now();
println!("pre_append Time:{:?}", end.duration_since(start).unwrap());
let start = time::SystemTime::now();
for _i in 0..N {
normal_append();
}
let end = time::SystemTime::now();
println!(
"normal_append Time:{:?}",
end.duration_since(start).unwrap()
);
}
//不分配内存模式
fn normal_append() -> String {
let mut buf = String::new();
let mut i: usize = 0;
while i < L {
buf.push('s');
i += 1;
}
return buf;
}
//预分配内存模式
fn pre_append() -> String {
let mut buf = String::with_capacity(L);
let mut i: usize = 0;
while i < L {
buf.push('s');
i += 1;
}
return buf;
}
#[cfg(test)]
mod tests {
use crate::normal_append;
use crate::pre_append;
use std::fmt::Error;
const N: isize = 50000;
#[test]
fn test_pre_append() -> Result<(), Error> {
for _i in 0..N {
pre_append();
}
Ok(())
}
#[test]
fn test_normal_append() -> Result<(), Error> {
for _i in 0..N {
normal_append();
}
Ok(())
}
}
```
### 下面是各种模式下的运行结果:
#### 测试模式的比拼
`go`语言:
```
$ go test -v .
=== RUN TestNormalAppend
TestNormalAppend
--- PASS: TestNormalAppend (11.51s)
=== RUN TestPreAppend
TestPreAppend
--- PASS: TestPreAppend (6.63s)
PASS
ok app_test_bench 18.146s
```
运行 `TestNormalAppend`的时间是11.51秒。
运行`TestPreAppend`的时间是6.63秒。
`rust`语言:
```
$ cargo t
Compiling string_test v0.1.0 (/home/fuhz/src/rust_test/string_test)
Finished test [unoptimized + debuginfo] target(s) in 0.37s
Running unittests src/main.rs (target/debug/deps/string_test-cf0723c9e88581f5)
running 2 tests
test tests::test_normal_append has been running for over 60 seconds
test tests::test_pre_append has been running for over 60 seconds
test tests::test_pre_append ... ok
test tests::test_normal_append ... ok
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 78.64s
```
`test_normal_append`对应`go`程序中的`TestNormalAppend`,`test_pre_append`对应`go`程序中的`TestPreAppend`,两者的运行时间都超过了60秒,无法显示精确时间。
#### Debug模式的比拼
```
$ go build
$ ./app_test_bench
preAppend Time:5.864950476
normalAppend Time:12.123574635
cargo build
Compiling string_test v0.1.0 (/home/fuhz/src/rust_test/string_test)
Finished dev [unoptimized + debuginfo] target(s) in 0.27s
$ target/debug/string_test
pre_append Time:69.011713959s
normal_append Time:69.313903563s
```
`go`程序中,`preAppend`用时5.865秒,`normalAppend`用时12.123秒;`rust`程序中,`pre_append`用时69.012秒,`normal_append`用时69.314秒。
#### Release模式的比拼
```
$ go build -ldflags '-s -w'
$ ./app_test_bench
preAppend Time:6.072494913
normalAppend Time:10.464082479
$ cargo build --release
Compiling string_test v0.1.0 (/home/fuhz/src/rust_test/string_test)
Finished release [optimized] target(s) in 0.30s
$ target/release/string_test
pre_append Time:10.794002015s
normal_append Time:10.808211814s
```
`go`程序中,`preAppend`用时6.072秒,`normalAppend`用时10.464秒;`rust`程序中,`pre_append`用时10.794秒,`normal_append`用时10.808秒。
有疑问加站长微信联系(非本文作者))
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
关注微信3224 次点击
添加一条新回复
(您需要 后才能回复 没有账号 ?)
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码` - 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传