与其他系统编程语言(如 C)中通常使用的函数相比,Rust 风格的方法调用方法是否有任何开销?

Is there any overhead in Rust-style method calling approach compared to the usual use of functions in other system programming languages such as C?

我刚开始使用 Rust,印象中是它的所有权范式。阅读tutorial,我发现了下面的代码

let secret_number = rand::thread_rng().gen_range(1, 101);

我假设通过调用其方法实例化 rand::ThreadRng 结构后生成一个随机整数。

像 C 那样简单地使用函数不是更好吗?由于 Rust 将自己定位为一种系统编程语言,如果我的猜想是正确的,那么这种支持创建结构和使用它们的方法的选择似乎不太理想。

Is there any overhead in Rust-style method calling approach compared to [...] C?

没有

两种语言都可以生成完全相同的机器指令。表达概念的语法并不要求生成的代码效率低下(在许多情况下恰恰相反)。

Isn't it better for performance simply to use functions like in C?

方法函数。

Rust 方法在概念上与采用指针的 C 函数相同:

生锈

struct Foo {
    a: i32,
}

impl Foo {
    fn add(&self, b: i32) -> i32 {
        self.a + b
    }
}

C

struct Foo {
    int a;
};

int Foo_add(struct Foo *self, int b) {
    return self->a + b;
}

这里两种语言之间没有重要区别。

Rust 有免费 功能以及相关 功能;如果您不需要引用数据,则不需要:

生锈

struct Foo {
    a: i32,
}

// Free function
fn foo() -> Foo { 
    Foo { a: 42 }
}

impl Foo {
    // Associated function
    fn new() -> Foo {
        Foo { a: 99 }
    }
}

C

struct Foo {
    int a;
};

struct Foo foo() {
    struct Foo foo = { 42 };
    return foo;
}

struct Foo Foo_new() {
    struct Foo foo = { 99 };
    return foo;
}

Rust 也有零大小的类型,它们看起来有关联数据,但在编译代码中消失了:

生锈

// Zero size
struct Foo;

impl Foo {
    fn add_one(&self, b: i32) -> i32 {
        b + 1
    }
}

C

int Foo_add_one(int b) {
    return b + 1;
}

creating structures and using their methods seems to be quite suboptimal

创建结构和相关方法在 C 代码中常见。我会说这很可能是 占主导地位的 编码风格;我不知道为什么你会说它不是最理想的。


您的示例案例无法进行比较,因为您没有提供 任何 C 代码,更不用说等效的代码了。 ThreadRng 做了 很多 工作来提供更好的随机数生成体验:

ThreadRng uses ReseedingRng wrapping the same PRNG as StdRng, which is reseeded after generating 32 MiB of random data. A single instance is cached per thread and the returned ThreadRng is a reference to this instance — hence ThreadRng is neither Send nor Sync but is safe to use within a single thread. This RNG is seeded and reseeded via EntropyRng as required.

"traditional" 随机数生成器 (rand) 具有全局状态(这通常是一件坏事),但概念上看起来像:

struct RngState {
    int whatever_goes_here;
};

static struct RngState GLOBAL_STATE = { 0 };

int rand_with_state(struct RngState *state) {
    return state->whatever_goes_here++;
}

int rand() {
    return rand_with_state(&GLOBAL_STATE);
}

请注意,它仍然使用指向数据的指针