Spoiler: C ++ n'est ni plus rapide ni plus lent, et généralement ce n'est pas le point. Cet article est une continuation des glorieuses traditions de démystification des mythes des grandes entreprises russes sur la langue rouille. Le précédent était " Allez plus vite que Rust, Mail.Ru Group a pris des mesures ."
Récemment, j'ai essayé d'attirer un collègue, un sishnik d'un département voisin, Sombrecôté de la rouille. Mais ma conversation avec un collègue n'a pas fonctionné. Parce que, citez:
En 2019, j'étais à la conférence C ++ CoreHard, j'ai écouté le rapport d'AntonantoshkkaPolukhina sur l'indispensable C ++. Selon Anton, Rust est encore jeune, pas très rapide et pas si sûr du tout.
Anton Polukhin est le représentant de la Russie à l'ISO lors des réunions internationales du groupe de travail sur la normalisation C ++, l'auteur de plusieurs propositions acceptées pour la norme pour le langage C ++. Anton est vraiment une personne cool et autoritaire en matière de C ++. Mais le rapport contient de sérieuses erreurs factuelles concernant Rust. Prenons-les à part.
Nous parlons de ce rapport de 13h00 Ă 22h35 .
Table des matières
â„–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++, .
Cependant, de la part d'experts reconnus, je m'attends à une couverture équilibrée de la situation, qui, au minimum, ne contient pas d'erreurs factuelles grossières.
Un grand merci Ă Dmitry Kashitsyn et Alexei Kladov pour avoir relu l'article.