Spoiler: C ++ ist weder schneller noch langsamer, und im Allgemeinen ist dies nicht der Punkt. Dieser Artikel ist eine Fortsetzung der glorreichen Traditionen, die Mythen groĂźer russischer Unternehmen ĂĽber die Rust-Sprache zu entlarven. Der vorherige war " Gehen Sie schneller als Rust, Mail.Ru Group nahm Messungen vor ."
Kürzlich habe ich versucht, einen Kollegen, einen Sishnik aus einer benachbarten Abteilung, zu locken DunkelSeite von Rust. Aber mein Gespräch mit einem Kollegen hat nicht geklappt. Weil, Zitat:
2019 war ich auf der C ++ CoreHard-Konferenz und habe Antons Bericht angehörtAntoshkkaPolukhina über das unverzichtbare C ++. Laut Anton ist Rust noch jung, nicht sehr schnell und überhaupt nicht so sicher.
Anton Polukhin ist der Vertreter Russlands in der ISO bei internationalen Treffen der Arbeitsgruppe für Standardisierung C ++, der Autor mehrerer akzeptierter Vorschläge für den Standard für die Sprache C ++. Anton ist wirklich eine coole und maßgebliche Person in Sachen C ++. Der Bericht enthält jedoch einige schwerwiegende sachliche Fehler in Bezug auf Rust. Nehmen wir sie auseinander.
Wir sprechen ĂĽber diesen Bericht von 13:00 bis 22:35 Uhr .
Inhaltsverzeichnis
â„–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++, .
Von anerkannten Experten erwarte ich jedoch eine ausgewogene Berichterstattung über die Situation, die zumindest keine groben sachlichen Fehler enthält.
Vielen Dank an Dmitry Kashitsyn und Alexei Kladov fĂĽr die ĂśberprĂĽfung des Artikels.