1.83K subscribers
3.3K photos
132 videos
15 files
3.58K links
Блог со звёздочкой.

Много репостов, немножко программирования.

Небольшое прикольное комьюнити: @decltype_chat_ptr_t
Автор: @insert_reference_here
Download Telegram
Я так люблю, когда программисты оптимизируют количество нажатий клавиш. Подозреваю, что сэкономленное время они тратят на саморазвитие
19😁4👍1🔥1
#prog #rust #rustreleasenotes

Вышла версия Rust 1.72.0! Как обычно, тут только то, что интересует меня, а полный ченджлог тут.

▪️Офигенно полезная вещь: компилятор теперь говорит о том, что имена не определены из-за того, что определяющий их код находится под неактивным #[cfg].

▪️Компилятор теперь не имеет ограничения на время вычисления const fn (технически ограничено включённым по умолчанию линтом, но его можно и отключить). При этом он всё ещё выдаёт предупреждения, если код из-за этого долго компилируется, но интервал между ними удваивается после каждого вывода, чтобы не спамить в консоль.

▪️Несколько линтов из Clippy втащили в компилятор, а именно:

🔹undropped_manually_drops (warn по умолчанию) — попытка явно дропнуть ManuallyDrop.
🔹invalid_utf8_in_unchecked — разделив при этом на две:
🔸invalid_utf8_in_unchecked (deny по умолчанию) при вызове std::str::from_utf8_unchecked{, _mut} на невалидном UTF-8 — это всегда неопределённое поведение
🔸invalid_from_utf8 (warn по умолчанию) при вызове std::str::from_utf8{, _mut} на невалидном UTF-8 — такой вызов всегда возвращает ошибку
🔹cmp_nan как invalid_nan_comparisons (warn по умолчанию) — явное сравнение с NaN (такое сравнение всегда возвращает ложь)
🔹cast_ref_to_mut — при кастах из &T в &mut T. allow по умолчанию, но исключительно из-за наличия false positive, к следующему релизу планируют сделать уже deny по умолчанию.

▪️Для указания трейт-объектов теперь не нужно выписывать ассоциированные типы, на которых есть ограничение Self: Sized. Это консистентно с where Self: Sized на методах, наличие которых не влияет на object safety, но которые нельзя вызвать на трейт-объектах. Отмечу, что указывать остальные типы для трейт-объектов всё также надо.

▪️Отправляющая половинка mpsc-канала из std наконец-то реализует Sync.

▪️Уточнено поведение HashSet::insert: если ключ уже есть в множестве, то он не заменяется, а переданный ключ дропается.

▪️Как я уже говорил, select_nth_unstable теперь имеет реальную задокументированную линейную сложность.

▪️Опять-таки, как я уже рассказывал, ptr_eq на счётчиках ссылок теперь сравнивает лишь адреса.

▪️Стабилизирован impl TryFrom<&OsStr> for &str

▪️В const-контексте теперь можно использовать CStr::from_bytes_with_nul, CStr::to_bytes, CStr::to_bytes_with_nul и CStr::to_str.
👍8🔥2
😁14
Не тратьте деньги с умом.

Ум вам ещё пригодится.
👍1
Некоторые говорят писать unsigned int, большинство говорят писать просто unsigned, я же говорю писать на Rust
👌11😁6
Погодите, это правильные пчелы? Или неправильные?
9
Вечерний Даня (danya.ru)
Погодите, это правильные пчелы? Или неправильные?
Напоминает спиральный рост кристаллов. И причина, видимо, схожая: винтовая дислокация решётки (атомов кристалла и отдельных сот соответственно)
🙏4🤡1
❤‍🔥23🙏6👍4🌚4🤡2👎1👏1
Это даже не #game #meme, это жиза
Forwarded from shitposting 3.0 [+ dragons]
😢21👍3
"Христианство — это духовный БДСМ"

(c) не я

#quotes
Сирена страдает без воды
😢54
Не хватает бара RGB
👍10😁5🤔3
Папищеки
Вы такие харошие
22🤮4🥰3👌2👍1💩1🤡1
Forwarded from PB
мужчинам нужно обещать весь мир и дарить цветочки, мороженое и оргазм.
🤮16❤‍🔥11👍2👎1💩1🤡1
#prog

Подписчики, я обескуражен.

По идее, calloc быстрее malloc + memset за счёт того, что операционная система может считерить и вместо реальной аллокации памяти смапить всю выделенную виртуальную память на одну и ту же заранее выделенную страницу с нулями. С другой стороны, при последующей работе обращение к странице вызовет дорогостоящий page fault, который заставит операционную систему реально выделить память.

Я решил замерить разницу при помощи кода, который для нескольких количеств страниц выделяет память: сначала при помощи calloc и читает по первому байту из каждой выделенной страницы, а потом при помощи malloc и перезаписывает всё нулями.

Код выглядит так:

fn get_page_size() -> usize {
// платформо-специфичный код
}

use std::alloc::{alloc, alloc_zeroed, dealloc, Layout};
use std::time::Instant;

fn main() {
let page_size = get_page_size();
println!("page size = {page_size} bytes\n");

for n_pages in (0..5).map(|p| 2 * 10_usize.pow(p)) {
let layout = Layout::from_size_align(page_size * n_pages, 1).unwrap();
println!("n pages = {n_pages}");

let start = Instant::now();
let ptr = unsafe { alloc(layout) };
assert!(!ptr.is_null());
unsafe {
std::hint::black_box(ptr).write_bytes(0, layout.size());
}
unsafe { dealloc(ptr, layout) }
let duration = start.elapsed();
println!("with alloc + memset:\t{duration:?}");

let start = Instant::now();
let ptr = unsafe { alloc_zeroed(layout) };
assert!(!ptr.is_null());
std::hint::black_box(ptr);
for n in 0..n_pages {
std::hint::black_box(unsafe { ptr.add(n * page_size).read() });
}
unsafe { dealloc(ptr, layout) }
let duration = start.elapsed();
println!("with calloc:\t\t{duration:?}");

println!();
}
}

Когда я запускаю этот код на Rust playground (который, я напомню, на Linux), я получаю такие результаты (примерно, потому что конкретные цифры от запуска к запуску, разумеется, разнятся):

n pages = 2
with alloc + memset: 4.061µs
with calloc: 660ns

n pages = 20
with alloc + memset: 28.651µs
with calloc: 2.27µs

n pages = 200
with alloc + memset: 728.031µs
with calloc: 236.287µs

n pages = 2000
with alloc + memset: 3.009318ms
with calloc: 1.227636ms

n pages = 20000
with alloc + memset: 27.395091ms
with calloc: 9.131857ms

Видно, что calloc хоть и явно не бесплатный (даже не смотря на то, что лишь читаем, а не пишем), но всё равно быстрее malloc + memset даже на двух страницах памяти.

А вот какой результат я получаю на своём ноутбуке, который на Windows:

n pages = 2
with alloc + memset: 11.3µs
with calloc: 1.5µs

n pages = 20
with alloc + memset: 38.4µs
with calloc: 4.7µs

n pages = 200
with alloc + memset: 392.2µs
with calloc: 55.5µs

n pages = 2000
with alloc + memset: 2.6747ms
with calloc: 1.8153ms

n pages = 20000
with alloc + memset: 37.8768ms
with calloc: 24.9391ms

Видно, что calloc и тут быстрее, но уже далеко не так сильно. Более того, если выделять по 200 000 страниц памяти (что не получается сделать на playground из-за квот по памяти, видимо), то получается что-то вроде такого:

n pages = 200000
with alloc + memset: 345.1817ms
with calloc: 318.5761ms

То есть относительная разница, кажется, стремится к нулю (а в некоторых запусках calloc даже медленнее).

Посему вопрос: откуда такая разница в поведении? Существенна ли тут разница в OS или ещё играет роль (очевидная) разница в железе? Размер страниц памяти, если что, одинаковый, я проверял.
10
🤡101💩7🤮3