Есть ли издержки в подходе к вызову метода в стиле Rust по сравнению с [...] C?
номер
Точно одинаковые машинные инструкции могут быть сгенерированы на двух языках. Синтаксис для выражения концепций не требует, чтобы результирующий код был неэффективным (и во многих случаях верно обратное).
Не лучше ли для производительности просто использовать функции, как в C?
Методы являются функциями.
Метод Rust концептуально аналогичен функции C, принимающей указатель:
Rust
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 имеет свободные функции, а также связанные функции; если вам не нужна ссылка на данные, вам не нужно:
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 также имеет типов нулевого размера , которые выглядят так, как будто у них есть связанные данные, но которые исчезают в скомпилированном коде:
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;
}
создание структур и использование их методов представляется довольно неоптимальным
Создание структур и связанных методов распространено в C-коде. Я бы сказал, что это, скорее всего, преобладающий стиль кодирования; Я не знаю, почему вы говорите, что это неоптимально.
Ваш пример не подходит для сравнения, потому что вы не предоставили любой C-код, тем более что-то эквивалентное. ThreadRng
выполняет много работы, чтобы обеспечить лучший опыт для генерации случайных чисел:
ThreadRng
использует ReseedingRng
, оборачивая тот же PRNG, что и StdRng
, который повторяется после генерации 32 МБ случайных данных. Один экземпляр кэшируется для каждого потока, и возвращенный ThreadRng
является ссылкой на этот экземпляр - следовательно, ThreadRng
не является ни Send
, ни Sync
, но безопасен для использования в одном потоке. Этот ГСЧ посеян и посеян через EntropyRng
по мере необходимости.
«Традиционный» генератор случайных чисел (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);
}
Обратите внимание, что все еще использует указатель на данные .