优雅测函数执行时间(Rust, Golang, Python)

  • 更新于 26 5月 2021

有时非常需要测量函数的执行时间。在其他语言中很容易实现比如像 Python 与 Golang,而在 Rust 实现即相对比较困难。

因此,本文将演示一些衡量函数执行时间的方法与技巧。

本文从最简单的版本到可重用的版本均有,同时也包括了 Python 和 Golang。

基础版本

在任何语言中,你都可以简单地通过计算时间差以测量函数的执行时间。

例如,

fn main() { let start = Instant::now(); expensive_func(); let duration = start.elapsed(); println!("Time elapsed is: {:?}", duration); }

这种实现很容易,但并不优雅且不可重用。

可重用版本

简短版 : Rust

你可以在这里拿到代码:

Rust playground

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 上找到代码: Rust 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); }