Spoiler: C ++ no es ni más rápido ni más lento, y generalmente este no es el punto. Este artĂculo es una continuaciĂłn de las gloriosas tradiciones de desacreditar los mitos de las grandes compañĂas rusas sobre el lenguaje Rust. El anterior fue " Ir más rápido que Rust, Mail.Ru Group tomĂł medidas ".
Recientemente, traté de atraer a un colega, un sishnik de un departamento vecino, a Oscurolado de óxido. Pero mi conversación con un colega no funcionó. Porque cita:
En 2019, estuve en la conferencia C ++ CoreHard , escuchĂ© el informe de AntonAntoshkkaPolukhina sobre el indispensable C ++. SegĂşn Anton, Rust todavĂa es joven, no es muy rápido y no es tan seguro en absoluto.
Anton Polukhin es el representante de Rusia en ISO en las reuniones internacionales del grupo de trabajo sobre estandarización C ++, el autor de varias propuestas aceptadas para el estándar para el lenguaje C ++. Anton es realmente una persona genial y autoritaria en materia de C ++. Pero el informe contiene algunos errores de hecho serios con respecto a Rust. Vamos a desarmarlos.
Estamos hablando de este informe de 13:00 a 22:35 .
Tabla de contenido
â„–1. Rust C++.
(link:godbolt):
(13:35):
. ! . C++ Rust .
, , . , , . , Rust [-2147483648, 2147483647], C++ [-46340, 46340]. ? ?
-46340 46340 — , std::int32_t
. - signed overflow. , PVS-Studio. , , CI , :
runtime error: signed integer overflow: 46341 * 46341 cannot be represented in type 'int'
runtime error: signed integer overflow: -46341 * -46341 cannot be represented in type 'int'
Rust .
, (13:58):
, C++ . . C++ . Rust' , . . Rust' , , , . , , Rust . - .
, Rust, , Rust LLVM — , Clang. , Rust «» C++ . , , . C++ . .
, int'a:
unsigned MAX_INT = 2147483647;
int hash_code(std::string x) {
int h = 13;
for (unsigned i = 0; i < 3; i++) {
h += h * 27752 + x[i];
}
if (h < 0) h += MAX_INT;
return h;
}
, , «bye», ( , ) . , , , MAX_INT .
PVS-Studio, . 27752 3 , , , - .
Rust (link:playground):
fn hash_code(x: String) -> i32 {
let mut h = 13i32;
for i in 0..3 {
h += h * 27752 + x.as_bytes()[i] as i32;
}
if h < 0 {
h += i32::max_value();
}
return h;
}
fn main() {
let h = hash_code("bye".to_string());
println!("hash: {}", h);
}
Debug Release , : wrapping*, saturating*, overflowing* checked*.
, .
— , C++ . . , , «» , .
â„–2. Rust .
(link:godbolt):
(15:15):
Rust' C++ , bar
. -, - . … , Rust , , UB — , , - . - , - . -- .
. - , NOP bar
C++, Rust. LLVM.
LLVM IR , (link:godbolt):
ret i32 undef
— , LLVM.
LLVM 2006 . , , LLVM . , . LLVM 6 llvm.sideeffect, 2019 rustc -Z insert-sideeffect
, llvm.sideeffect
. (link:godbolt). , stable rustc .
C++ , LLVM Rust C.
, , LLVM, : " ". , Rust , , .
â„–3. Rust .
(16:00):
. Rust. bar
foo
. , Rust : - , . C++ . Rust . - .
(link:godbolt):
Rust , . -ftrapv
C++ -C overflow-checks=on
Rust, . C++ ud2
, "Illegal instruction (core dumped)", Rust core::panicking::panic
, . core::panicking::panic
:
$ ./signed_overflow
thread 'main' panicked at 'attempt to multiply with overflow', signed_overflow.rs:6:12
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
"" , ? x86-64 , 16 , call
8- , . , push rax. Rust, C++(link:godbolt):
C++, Rust , push rbx
. Q.E.D.
, C++ -ftrapv
, . , Rust -C overflow-checks=on
, (link:godbolt) C++, . -ftrapv
gcc 2008 .
â„–4. Rust C++.
(18:10):
Rust ...
, Rust', . , "" , 17:30(link:godbolt):
, , , → .
2019 CppCon There Are No Zero-cost Abstractions Chandler Carruth. 17:30 - , std::unique_ptr
(link:godbolt). - noexcept
, rvalue , std::move
. Rust . . Rust extern "Rust"
unsafe
, (link:godbolt):
Rust . noexcept
, rvalue std::move
. . , , .
2019 Rust C++ Benchmarks Game. C++ . . .
№5. C → ++ — noop, C → Rust — PAIN!!!!!!!
(18:30):
, Rust , . , , . ++ , . Rust' - .
.
, Rust , , . Starcraft, .
, Rust cargo, . , , . 2020 crates.io 40 000 .
:
# Cargo.toml
[dependencies]
flate2 = "1.0"
cargo . flate2 , miniz, C, Rust. flate2 .
â„–6. unsafe Rust.
(19:14):
unsafe
Rust', , , .
Rust' .
, unsafe
— , Rust , unsafe
:
- ;
- unsafe ;
- ;
- unsafe ;
union
.
Rust . lifetime-, unsafe
. , , - . You can’t "turn off the borrow checker" in Rust.
unsafe
" , ". , , . , . , malloc
NULL , Rust . , , , malloc
, : " , ; , , ". unsafe
.
â„–7. Rust .
(19:25):
C++ , , - - , - null . . Rust . - . Rust , , C++.
Microsoft, 70% , Rust . , Rust.
, unsafe
Rust, , … , , . , , Rust .
, , , Rust C++ , Rust . Rust . , unsafe
.
unsafe
:
// Warning: Calling this method with an out-of-bounds index is undefined behavior.
unsafe fn unchecked_get_elem_by_index(elems: &[u8], index: usize) -> u8 {
*elems.get_unchecked(index)
}
slice::get_unchecked
— unsafe
, . get_elem_by_index
, , . unsafe
(link:playground):
// Warning: Calling this method with an out-of-bounds index is undefined behavior.
unsafe fn unchecked_get_elem_by_index(elems: &[u8], index: usize) -> u8 {
*elems.get_unchecked(index)
}
fn main() {
let elems = &[42];
let elem = unsafe { unchecked_get_elem_by_index(elems, 0) };
dbg!(elem);
}
, , . unsafe
.
, unsafe
(link:playground):
// Warning: Calling this method with an out-of-bounds index is undefined behavior.
unsafe fn unchecked_get_elem_by_index(elems: &[u8], index: usize) -> u8 {
*elems.get_unchecked(index)
}
fn get_elem_by_index(elems: &[u8], index: usize) -> Option<u8> {
if index < elems.len() {
let elem = unsafe { unchecked_get_elem_by_index(elems, index) };
Some(elem)
} else {
None
}
}
fn main() {
let elems = &[42];
let elem = get_elem_by_index(elems, 0);
dbg!(&elem);
}
, . , Rust ( slice::get
), , unsafe
Rust . unchecked_get_elem_by_index
, C.
LTO :
. , C(link:godbolt), , Rust.
â„–8. Rust .
(20:38):
X. . X, , . . . . , X, .
2018 , Rust, , , . , unsafe
safe
, , .
, (), unsafe, , .
, Mutex, RwLock, thread::spawn. . , Rust ; , Mutex , , , . ? .
, . " - C++" , C++, .
Sin embargo, de expertos reconocidos, espero una cobertura equilibrada de la situaciĂłn, que, como mĂnimo, no contiene errores de hecho graves.
Muchas gracias a Dmitry Kashitsyn y Alexei Kladov por revisar el artĂculo.