与其他系统编程语言(如 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);
}
请注意,它仍然使用指向数据的指针。
我刚开始使用 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
usesReseedingRng
wrapping the same PRNG asStdRng
, which is reseeded after generating 32 MiB of random data. A single instance is cached per thread and the returnedThreadRng
is a reference to this instance — henceThreadRng
is neitherSend
norSync
but is safe to use within a single thread. This RNG is seeded and reseeded viaEntropyRng
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);
}
请注意,它仍然使用指向数据的指针。