优雅测函数执行时间(Rust, Golang, Python)
有时非常需要测量函数的执行时间。在其他语言中很容易实现比如像 Python 与 Golang,而在 Rust 实现即相对比较困难。
因此,本文将演示一些衡量函数执行时间的方法与技巧。
本文从最简单的版本到可重用的版本均有,同时也包括了 Python 和 Golang。
Table of Contents
基础版本
在任何语言中,你都可以简单地通过计算时间差以测量函数的执行时间。
例如,
fn main() {
let start = Instant::now();
expensive_func();
let duration = start.elapsed();
println!("Time elapsed is: {:?}", duration);
}
这种实现很容易,但并不优雅且不可重用。
可重用版本
简短版 : Rust
你可以在这里拿到代码:
fn main() {
measure_time(able_to_pass);
// 带参数的无法工作
// measure_time(able_to_pass_with_parameter);
// 但是你可以通过闭包来完成这个工作
measure_time(|| {
able_to_pass_with_parameter("test".to_string());
});
measure_time(|| {
sleep(Duration::new(1, 0));
println!("works!");
});
}
fn able_to_pass() {
println!("works! in function");
}
fn able_to_pass_with_parameter(x: String) {
println!("works! in function with {}", x);
}
// https://stackoverflow.com/a/25182801/8587335
fn measure_time<F: FnOnce()>(func: F) {
let start = Instant::now();
func();
let duration = start.elapsed();
println!("Time elapsed is: {:?}", duration);
}
接下来,我们将使用 Python 和 Golang 的代码来简单演示一下我们到底想要什么样的。
在 Python 中
写 Python 既轻松又舒适,尽管它牺牲了可能最重要的性能。
对于衡量时间而言,你可以通过以下代码实现:
# 更多的细节:https://stackoverflow.com/a/803626/8587335
def measure_time(func):
start_time = time.time()
_ = func()
end_time = time.time()
print("Time: {} seconds".format(end_time - start_time))
# 函数用lambda的特性来传递
measure_time(lambda: expensive_func())
# 你可以同样重用代码来避免写与时间相关的代码
measure_time(lambda: second_expensive_func())
在 Golang 中
在 Golang 中编写类似 python 这样的代码并不容易。
但是 Golang 可以使用 defer
。 真是一个好消息!
此版本的代码是我能找到的最简单和实用的代码。你可能会需要用到它。
// 来源: https://dev.to/rubiin/measure-function-execution-time-in-golang-177l
func measureTime(start time.Time, name string) {
elapsed := time.Since(start)
log.Printf("Time for %s: %s", name, elapsed)
}
func expensive_func() {
defer measureTime(time.Now(), "name")
// 开始你的函数计算
// ...
}
在 Rust 中
在 Rust 中编写类似 Python 和 Golang 之类的代码要困难得多,因为将函数作为参数传递确实很困难。
同时,你也很难轻松实现函数参数的动态分发,这是一个令人头疼的问题。
但是后来我突然在这里中发现了这一点,这对我很有启发。
您可以在 playground 上找到代码:
use std::thread::sleep;
use std::time::{Duration, Instant};
fn main() {
measure_time(able_to_pass);
let mut i = 0;
measure_time(|| {
i = able_to_pass_with_return();
});
// result: 1
println!("i = {}", i);
// 带参数的无法工作
// measure_time(able_to_pass_with_parameter);
// 但是你可以通过closure来完成
measure_time(|| {
able_to_pass_with_parameter("test".to_string());
});
measure_time(|| {
println!("works!");
sleep(Duration::new(1, 0));
});
}
fn able_to_pass() {
println!("works! in function");
}
fn able_to_pass_with_return() -> i32 {
println!("works! in function (return)");
return 1;
}
fn able_to_pass_with_parameter(x: String) {
println!("works! in function with {}", x);
}
// https://stackoverflow.com/a/25182801/8587335
fn measure_time<F: FnOnce()>(func: F) {
let start = Instant::now();
func();
let duration = start.elapsed();
println!("Time elapsedpsed in is: {:?}", duration);
}
The End