背景
最近因为工作需要,一直在学C++。偶尔也看看rust,因为rust太香了。但是大部分时间都还是在使用python。
看到网上有很多对比语言速度的文章,说什么rust吊打C++之类的,或者说什么python的numba吊打C++之类的。然后我也想做一期这样的内容。
那么基于我现在的水平,对一个特定的问题,使用不同的语言做比较。看看不同语言的速度如何。
问题
这个问题就是最简单的euler14问题:
就是计算一个正整数要经过多少步可以到1。每一步条件是:
- 如果是偶数,那么就除以2,得到下一个数字。
- 如果是奇数,那么就要乘以3再加一,得到下一个数字。
查看每一数值要走多少步。比如13这个数值到1需要走10步。那么找到0 ~ 100,000,000
里面步数最长的数值和对应的步数。
用户水平
- 对python掌握:大概是使用了5年的R语言,3年左右的python。
- 对c++掌握:大概是学习了两个星期的C++(只是看了C++ primer plus)
- 对rust掌握:学习了大概有1个星期的rust(只是看了rust官方中文文档)。
电脑配置
1. 硬件
- 电脑型号:MacBook Pro (16-inch, 2019)
- 电脑处理器:2.6 GHz 六核Intel Core i7
- 电脑内存:16 GB 2667 MHz DDR4
2. 软件
- clang++版本
Apple clang version 13.0.0 (clang-1300.0.29.30)
Target: x86_64-apple-darwin21.2.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
- rust版本
rustc --version
rustc 1.58.0 (02072b482 2022-01-11)
cargo --version
cargo 1.58.0 (7f08ace4f 2021-11-24)
- python版本
Python 3.8.8 (default, Apr 13 2021, 12:59:45)
[Clang 10.0.0 ] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
代码部分
其实这个代码有很多优化的地方,网上也有很多优化的思路,但是我都没有借鉴。目的有两个:
- 就是想从我现在的这个水平出发,看看写出来的代码的效果。
- 使用同一套直白的数据处理思路,保证各个语言使用的都是同一套最简单的逻辑。看看他们到底优化怎么样。
- 所以语言没有开启任何优化。(但是后来被评论区的大佬教做人了,还是再把代码优化一遍)
c++部分
#include <iostream>
#include <chrono>
using namespace std;
void func1() {
int big_epoch = 1;
int big_num = 1;
for (int index = 3; index <= 100000000; index++) {
long int mydata = index;
int epoch = 1;
while (true) {
// cout << "mydata : " << mydata << endl;
if (mydata == 1) {
break;
}
mydata = mydata % 2 == 1 ? mydata * 3 + 1 : mydata / 2;
epoch += 1;
}
if (epoch > big_epoch) {
big_epoch = epoch;
big_num = index;
}
}
cout << "epoch: " << big_epoch << " number: " << big_num << endl;
}
int main() {
auto t = chrono::system_clock::now();
func1();
cout << (chrono::system_clock::now() - t).count() * 1e-6 << endl;
}
运行时间:
- 其中C++不开O3一共使用了275.583秒。
- C++开了O3用时31秒。
rust版本
use chrono::prelude::*;
fn func5() {
let mut bigepoch = 1;
let mut bignumber = 1;
for index in 3..100000000 {
let mut mydata = index as i64;
let mut epoch = 1;
loop {
if mydata == 1 {
break;
}
if mydata % 2 == 1 {
mydata = mydata * 3 + 1;
} else {
mydata = mydata / 2;
}
epoch += 1;
// println!("index: {}, mydata: {}", index, mydata);
}
if epoch > bigepoch {
bigepoch = epoch;
bignumber = index;
}
}
println!("final epoch: {}, number: {}", bigepoch, bignumber);
}
fn main() {
println!("start run~");
let t1: DateTime<Local> = Local::now();
func5();
let t2: DateTime<Local> = Local::now();
let t3 = t2 - t1;
println!("total time: {}", t3);
}
运行时间:其中rust用了28.8秒。
python版本
import time
def func():
big_epoch, big_num = 1, 1
for index in range(3, 100000000):
mydata = index
epoch = 1
while True:
if mydata == 1:
break
if mydata % 2 == 1:
mydata = mydata * 3 + 1
else:
mydata = mydata / 2
epoch += 1
if epoch > big_epoch:
big_epoch = epoch
big_num = index
print(f"epoch: {big_epoch} number: {big_num}")
if __name__ == '__main__':
t1 = time.time()
func()
t2 = time.time()
print(f"total time: {t2 - t1}")
运行时间:
时间太长了,跑不出来。这个版本太垃圾了。
总结
- 时间方面:rust最快,只是使用了28.8秒即可。 C++第二快,只是需要31秒即可(因为c++在打印的时候也是非常浪费时间);python是真的很慢。
- python真的是慢到让人怀疑人生。
- 基于我现在的水平还有未来的需求,应该还是会继续学习和使用C++。但是也会了解和继续掌握rust知识。