反驳《Golang、Rust的执行速度的对照,让人大吃一惊。》——不会别瞎说

wayslog · 2017-03-22 06:11:15 · 15492 次点击 · 预计阅读时间 3 分钟 · 大约8小时之前 开始浏览    
这是一个创建于 2017-03-22 06:11:15 的文章,其中的信息可能已经有所发展或是发生改变。

首先我无意引战,但是今天看到某位同学的文章里有某些错误,不得不指正一下。

原文地址:http://studygolang.com/articles/9628

1. 测量时间的时候我们使用 `std::time::SystemTime::elapsed` 即可,不必蹩脚的使用两个 system 输出出来还得手动算一下。(当然你说对Rust不熟也就无所谓了)

2. 最重要一点。 执行 rust 代码的时候请用 `--release` ,cargo 项目请直接执行 `cargo run --release`

在我本机的测试过程:

```

➜  demo pwd
/Users/wayslog/go/src/demo
➜  demo go version
go version go1.7.1 darwin/amd64
➜  demo cat demo.go
package main

import (
    "fmt"
    "runtime"
    "time"
)

func main() {
    runtime.GC()

    t := time.Now()
    sum := 0
    for i := 0; i < 20000; i++ {
        for j := 0; j < 20000; j++ {
            sum = sum + i*j
        }
    }
    fmt.Println(time.Now().Sub(t))
    fmt.Println(sum)
}
➜  demo go run demo.go
236.312079ms
39996000100000000
➜  demo go build
➜  demo ./demo
289.696142ms
39996000100000000
➜  demo cd ~/rust/baka
➜  baka git:(master) ✗ cat src/main.rs
use std::time::SystemTime;
fn main() {

    let sys_time = SystemTime::now();
    let mut x = 0;
    let mut i = 0;
    let mut y: u64 = 0;
    while x < 20000 {
        i = 0;
        while i < 20000 {
            y = y + x * i;
            i = i + 1;
        }
        x = x + 1;
    }

    println!("{:?}", sys_time.elapsed());
    println!("The value of y is: {}", y);
}
➜  baka git:(master) ✗ cargo run --release
    Finished release [optimized] target(s) in 0.0 secs
     Running `target/release/baka`
Ok(Duration { secs: 0, nanos: 0 })
The value of y is: 39996000100000000
➜  baka git:(master) ✗ cargo build --release
    Finished release [optimized] target(s) in 0.0 secs
➜  baka git:(master) ✗ ./target/release/baka
Ok(Duration { secs: 0, nanos: 0 })
The value of y is: 39996000100000000

```

Rust这里为什么会跑到0秒0ns呢?

将rust编译到asm我们能看到, 地址在这:https://is.gd/CyE36H

```

movabsq $39996000100000000, %rax

```

编译时计算掉了么?

OK,既然编译时计算掉了这个情况,那么,我们让用户自己输入数字吧,这样编译时计算总优化不掉吧?

 

```

➜  baka git:(master) ✗ cat src/main.rs
use std::time::SystemTime;
use std::env;

fn main() {
    let mut args = env::args();
    args.next().unwrap();
    let max_range = args.next().unwrap().parse::<u64>().expect("not num");
    let sys_time = SystemTime::now();

    let mut x = 0;
    let mut i = 0;
    let mut y: u64 = 0;
    while x < max_range {
        i = 0;
        while i < max_range {
            y = y + x * i;
            i = i + 1;
        }
        x = x + 1;
    }

    println!("{:?}", sys_time.elapsed());
    println!("The value of y is: {}", y);
}

➜  baka git:(master) ✗ cargo build --release
    Finished release [optimized] target(s) in 0.0 secs

➜  baka git:(master) ✗ ./target/release/baka 20000
Ok(Duration { secs: 0, nanos: 6000 })
The value of y is: 39996000100000000

➜  baka git:(master) ✗ ./target/release/baka 40000
Ok(Duration { secs: 0, nanos: 12000 })
The value of y is: 639968000400000000

```

这里,Rust编译器可能也做了其他的优化了,但是需要分析asm再来看了,这里不做赘述。

但是,无论怎么看, 6000 ns (0.006ms) 和 200 ms 都是数量级的差距吧?

总结一点,不会别瞎说,这位 gopher 不行啊,深表同情。

 


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

15492 次点击  
加入收藏 微博
18 回复  |  直到 1999-12-31 16:00:00
wayslog
wayslog · #1 · 8年之前

这帖子删的真快。。。

polaris
polaris · #2 · 8年之前
wayslogwayslog #1 回复

这帖子删的真快。。。

有人qq找我说,那篇文章引来了Rust社区的大争论,建议我把它线下,所以把它线下了

wayslog
wayslog · #3 · 8年之前
polarispolaris #2 回复

#1楼 @wayslog 有人qq找我说,那篇文章引来了Rust社区的大争论,建议我把它线下,所以把它线下了

恩,好吧。。我这反驳的也其实也没啥意义了。不过还是留着吧。。。警醒后人。。。

doomsplayer
doomsplayer · #4 · 8年之前
wayslogwayslog #1 回复

这帖子删的真快。。。

本站第五位会员来顶你

wayslog
wayslog · #5 · 8年之前
doomsplayerdoomsplayer #4 回复

#1楼 @wayslog 本站第五位会员来顶你

。。。42你工作不饱和啊……

iPixelOldC
iPixelOldC · #6 · 8年之前

我是说。。 一个无GC的语言怎么速度比有GC的还慢。。。

mortemnh
mortemnh · #7 · 8年之前

看最后结果都知道了RUST编译器肯定优化...否则4倍计算量耗时提高只有2倍=。=。不过无GC语言和有GC语言本身先天性就没可比性....

mortemnh
mortemnh · #8 · 8年之前

至于优化到底有多离谱.....上面函数等效于 sum := 0 for i := 0; i < num; i++ { sum = sum + i(num-1)num/2 } 这个跑一下就知道了,所以到底至于文章倒数第二句话的差距我也只能说呵呵.......二层嵌套函数和1层嵌套函数自然而然相差肯定不是一个量级...

wayslog
wayslog · #9 · 8年之前
mortemnhmortemnh #8 回复

至于优化到底有多离谱.....上面函数等效于 sum := 0 for i := 0; i < num; i++ { sum = sum + i*(num-1)*num/2 } 这个跑一下就知道了,所以到底至于文章倒数第二句话的差距我也只能说呵呵.......二层嵌套函数和1层嵌套函数自然而然相差肯定不是一个量级...

所以说编译原文作者自己本身一知半解的拿一个debug版本来拼速度这本身不是一件可笑的事情么?哦,对了,说不定你没看到原文。

原文中就大吹特吹 什么 “数量级的差距”(rust 的 debug 版本跑了2秒),所以才有了我的倒数第二句话。有因有果,话不可以说满,不然被打脸的时候乖乖站好。

另外。。。当然做过优化啊,但是我没仔细看到怎么优化的所以没把话说满,这难道不是一件需要谨慎的事情么?你推出公式来,当然就说明你比我在这里更厉害一点了,佩服。

我们来推算一下,20000^2 的算量用现在 3.0 GHZ的CPU算(假设每个指令都是一个时钟周期)大概也是 120ms左右(和C++表现一致,140ms)。

最后的最后,编译期优化就不是人家优化的好了么?你可以说借了LLVM的光,LLVM 优化也是人做的啊,对接LLVM也是人家 LLVM IR 搭的好,你说是不是?

Go,去做优化啊!

wayslog
wayslog · #10 · 8年之前
iPixelOldCiPixelOldC #6 回复

我是说。。 一个无GC的语言怎么速度比有GC的还慢。。。

GC不能代表执行速度的差异。 需要知道 析构 也是需要时间的。君不见很多 JVM 虚拟机在跑性能测试的时候都是关了GC再去跑的么,连析构扫描都没有。Go这里,对象这么少很可能都没有触发出GC来。

iPixelOldC
iPixelOldC · #11 · 8年之前
wayslogwayslog #10 回复

#6楼 @iPixelOldC GC不能代表执行速度的差异。 需要知道 析构 也是需要时间的。君不见很多 JVM 虚拟机在跑性能测试的时候都是关了GC再去跑的么,连析构扫描都没有。Go这里,对象这么少很可能都没有触发出GC来。 

zonyitoo
zonyitoo · #12 · 8年之前

不是很懂你们Go粉

mortemnh
mortemnh · #13 · 8年之前
wayslogwayslog #9 回复

#8楼 @mortemnh 所以说编译原文作者自己本身一知半解的拿一个debug版本来拼速度这本身不是一件可笑的事情么?哦,对了,说不定你没看到原文。 原文中就大吹特吹 什么 “数量级的差距”(rust 的 debug 版本跑了2秒),所以才有了我的倒数第二句话。有因有果,话不可以说满,不然被打脸的时候乖乖站好。 另外。。。当然做过优化啊,但是我没仔细看到怎么优化的所以没把话说满,这难道不是一件需要谨慎的事情么?你推出公式来,当然就说明你比我在这里更厉害一点了,佩服。 我们来推算一下,20000^2 的算量用现在 3.0 GHZ的CPU算(假设每个指令都是一个时钟周期)大概也是 120ms左右(和C++表现一致,140ms)。 最后的最后,编译期优化就不是人家优化的好了么?你可以说借了LLVM的光,LLVM 优化也是人做的啊,对接LLVM也是人家 LLVM IR 搭的好,你说是不是? Go,去做优化啊!

这里,Rust编译器可能也做了其他的优化了,但是需要分析asm再来看了,这里不做赘述。

但是,无论怎么看, 6000 ns (0.006ms) 和 200 ms 都是数量级的差距吧? 回的就是你这两句话而已。对编译器严重的优化避而不谈,二层嵌套优化成一层嵌套函数你嘴里的需要分析ASM你在搞笑么?其实你和之前那位半斤对八两而已.....

mortemnh
mortemnh · #14 · 8年之前
wayslogwayslog #9 回复

#8楼 @mortemnh 所以说编译原文作者自己本身一知半解的拿一个debug版本来拼速度这本身不是一件可笑的事情么?哦,对了,说不定你没看到原文。 原文中就大吹特吹 什么 “数量级的差距”(rust 的 debug 版本跑了2秒),所以才有了我的倒数第二句话。有因有果,话不可以说满,不然被打脸的时候乖乖站好。 另外。。。当然做过优化啊,但是我没仔细看到怎么优化的所以没把话说满,这难道不是一件需要谨慎的事情么?你推出公式来,当然就说明你比我在这里更厉害一点了,佩服。 我们来推算一下,20000^2 的算量用现在 3.0 GHZ的CPU算(假设每个指令都是一个时钟周期)大概也是 120ms左右(和C++表现一致,140ms)。 最后的最后,编译期优化就不是人家优化的好了么?你可以说借了LLVM的光,LLVM 优化也是人做的啊,对接LLVM也是人家 LLVM IR 搭的好,你说是不是? Go,去做优化啊!

还有原文我也看过,那位楼主我也不想评价什么,一个非GC语言能在纯计算上面比GC语言快本来就是扯淡的事情.....更何况是对于GC语言来说更不利的嵌套循环。本来根本对于那位的的测试结果我就觉得扯淡。本以为你的反驳问至少可以客观点,结果最后两句暴露出来你和那楼主真的没啥区别而已,所以我就把优化的实质摆出来了...别的不说了对于现代语言来说除了纯脚本语言外去跑一层循环函数基本上都在一个量级级别,真不知道你刻意摆出来0.006 和 200 说量级差距估计也就是忽悠不懂编译器优化的.....我举哪个例子其实就是常说的,比较语言的快慢根本就是扯淡.....算法上面的优化造成的结果远远超过语言间的差距。

wayslog
wayslog · #15 · 8年之前
mortemnhmortemnh #13 回复

#9楼 @wayslog 这里,Rust编译器可能也做了其他的优化了,但是需要分析asm再来看了,这里不做赘述。 但是,无论怎么看, 6000 ns (0.006ms) 和 200 ms 都是数量级的差距吧? 回的就是你这两句话而已。对编译器严重的优化避而不谈,二层嵌套优化成一层嵌套函数你嘴里的需要分析ASM你在搞笑么?其实你和之前那位半斤对八两而已.....

对编译器严重的优化避而不谈,二层嵌套优化成一层嵌套函数你嘴里的需要分析ASM你在搞笑么?

对于我确定的事情我习惯保持谨慎态度,我不觉得这是搞笑。

其实你和之前那位半斤对八两而已.....

一言不合就对别人妄下评论也是可以啊,这语气,啧啧。

wayslog
wayslog · #16 · 8年之前
wayslogwayslog #15 回复

#13楼 @mortemnh > 对编译器严重的优化避而不谈,二层嵌套优化成一层嵌套函数你嘴里的需要分析ASM你在搞笑么? 对于我确定的事情我习惯保持谨慎态度,我不觉得这是搞笑。 > 其实你和之前那位半斤对八两而已..... 一言不合就对别人妄下评论也是可以啊,这语气,啧啧。

对于我不确定的事情,本层回复笔误。

wayslog
wayslog · #17 · 8年之前
mortemnhmortemnh #14 回复

#9楼 @wayslog 还有原文我也看过,那位楼主我也不想评价什么,一个非GC语言能在纯计算上面比GC语言快本来就是扯淡的事情.....更何况是对于GC语言来说更不利的嵌套循环。本来根本对于那位的的测试结果我就觉得扯淡。本以为你的反驳问至少可以客观点,结果最后两句暴露出来你和那楼主真的没啥区别而已,所以我就把优化的实质摆出来了...别的不说了对于现代语言来说除了纯脚本语言外去跑一层循环函数基本上都在一个量级级别,真不知道你刻意摆出来0.006 和 200 说量级差距估计也就是忽悠不懂编译器优化的.....我举哪个例子其实就是常说的,比较语言的快慢根本就是扯淡.....算法上面的优化造成的结果远远超过语言间的差距。

首先,本文的重点在于像前一位楼主科普 release 和 debug 的区别,下面,反驳一下你的一些观点啊。

一个非GC语言能在纯计算上面比GC语言快本来就是扯淡的事情。.....更何况是对于GC语言来说更不利的嵌套循环。

哪里来的更何况???

别的不说了对于现代语言来说除了纯脚本语言外去跑一层循环函数基本上都在一个量级级别,真不知道你刻意摆出来0.006 和 200 说量级差距估计也就是忽悠不懂编译器优化的.....我举哪个例子其实就是常说的,比较语言的快慢根本就是扯淡.....算法上面的优化造成的结果远远超过语言间的差距。

大概你看句子没看懂?我在这里已经肯定了编译期优化的结果了。 我认同你的观点,算法上当然更重要。

但是请麻烦你自己反问自己几句:

0.006 和 200 是事实不?是!

有优化不?有啊!

我说了编译期优化了么?说了啊!

我给了优化公式了么?没有啊!

需要给么?不需要啊!

给出测试结果了没? 给出了啊!

结果耗时里面是 N^2 关系么?不是啊!

是N倍扩增么?是啊!

再送你一句Q&A:

Q: 不说编译器优化是不是因为你根本没看怎么优化的啊?

A: 是啊!

mortemnh
mortemnh · #18 · 8年之前
wayslogwayslog #17 回复

#14楼 @mortemnh 首先,本文的重点在于像前一位楼主科普 release 和 debug 的区别,下面,反驳一下你的一些观点啊。 > 一个非GC语言能在纯计算上面比GC语言快本来就是扯淡的事情。.....更何况是对于GC语言来说更不利的嵌套循环。 哪里来的更何况??? > 别的不说了对于现代语言来说除了纯脚本语言外去跑一层循环函数基本上都在一个量级级别,真不知道你刻意摆出来0.006 和 200 说量级差距估计也就是忽悠不懂编译器优化的.....我举哪个例子其实就是常说的,比较语言的快慢根本就是扯淡.....算法上面的优化造成的结果远远超过语言间的差距。 大概你看句子没看懂?我在这里已经肯定了编译期优化的结果了。 我认同你的观点,算法上当然更重要。 但是请麻烦你自己反问自己几句: 0.006 和 200 是事实不?是! 有优化不?有啊! 我说了编译期优化了么?说了啊! 我给了优化公式了么?没有啊! 需要给么?不需要啊! 给出测试结果了没? 给出了啊! 结果耗时里面是 N^2 关系么?不是啊! 是N倍扩增么?是啊! 再送你一句Q&A: Q: 不说编译器优化是不是因为你根本没看怎么优化的啊? A: 是啊!

RUST有没有优化,N^2算法变成N级线性算法,具不具备普遍优化性?不具备;那么0.006和200是真实对比?可笑,和之前那位用debug对比没任何区别,都是一种特定条件下的结果。

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传