<bgdev />free

Вход Регистрация

Защо така ?
1

0 1 2
#21539 (ツ) ФейкПрофил
Създадено на 12.12.2020, видяно: 1732 пъти.

Забелязах много интересен феномен,който не мога да си го обясня:

Вариант 1:


fn solve_part_one_1(input: &mut [i32]) -> Option<i32> {
    input.sort_unstable();

    let mut ones = 0;
    let mut threes = 1; 
    let mut prev = 0;

    for &i in input.iter() {
        let diff = i - prev;
        if diff == 1 {
            ones += 1;
        } else if diff == 3 {
            threes += 1;
        }

        prev = i;
    }

    if cfg!(debug_assertions) {
        println!("O:{}; T: {}; Result: {}", ones, threes, ones * threes);
    }

    Some(ones * threes)
}

Вариант 2:


fn solve_part_one_2(input: &mut [i32]) -> Option<i32> {
    input.sort_unstable();

    let mut sums = [0, 0, 1];
    let mut prev = 0;

    for &i in input.iter() {
        let diff = (i - prev) as usize;
        if diff <= 3 {
            sums[diff-1] += 1;
            prev = i;
        }
    }

    if cfg!(debug_assertions) {
        println!("O:{}; T: {}; Result: {}", sums[0], sums[2], sums[0] * sums[2]);
    }

    Some(sums[0] * sums[2])
}

Та това което не мога да си обясня е, защо вариант 1 се изпълнява за 2800 наносекунди, а вариант 2 - само за 1500. Защо така ?

Attached files:
FileSizeUploadedDownloadsMD5 hash
input.txt342 bytes12.12.202010994eb30170b55fe60a1d1fe872f7d160c
#21575 (ツ) saruman
Последно редактирано на 13.12.2020 от saruman, видяно: 1710 пъти.

Компилатора на Ръст е смотан? :-)

#21577 (ツ) |
Създадено на 13.12.2020, видяно: 1695 пъти.

По-малко сравнения? По-малък шанс за branch misprediction?

П.П. Двете програми не са еквивалентни.

#21578 (ツ) saruman
Последно редактирано на 13.12.2020 от saruman, видяно: 1688 пъти.
|

По-малко сравнения? По-малък шанс за branch misprediction?

П.П. Двете програми не са еквивалентни.

Аз на пръв поглед без да бенчмарквам бих предположил,че трябва да са точно обратните резултати,а именно там където се ползва [] оператора да е по-бавно,въпреки,че паметта е алокирана на едно място

#21579 (ツ) |
Създадено на 13.12.2020, видяно: 1673 пъти.
saruman
|

По-малко сравнения? По-малък шанс за branch misprediction?

П.П. Двете програми не са еквивалентни.

Аз на пръв поглед без да бенчмарквам бих предположил,че трябва да са точно обратните резултати,а именно там където се ползва [] оператора да е по-бавно,въпреки,че паметта е алокирана на едно място

Това всъщност показва, че компилатора на Ръст е доста добър.

#21580 (ツ) saruman
Създадено на 13.12.2020, видяно: 1665 пъти.
|
saruman
|

По-малко сравнения? По-малък шанс за branch misprediction?

П.П. Двете програми не са еквивалентни.

Аз на пръв поглед без да бенчмарквам бих предположил,че трябва да са точно обратните резултати,а именно там където се ползва [] оператора да е по-бавно,въпреки,че паметта е алокирана на едно място

Това всъщност показва, че компилатора на Ръст е доста добър.

Стига ве,и само заради branch prediction-а ли да прави такива разлики,забележи че долу ползва даже <= оператор,ако ползва само < още би трябвало да падне времето

#21581 (ツ) |
Създадено на 13.12.2020, видяно: 1657 пъти.
saruman
|
saruman
|

По-малко сравнения? По-малък шанс за branch misprediction?

П.П. Двете програми не са еквивалентни.

Аз на пръв поглед без да бенчмарквам бих предположил,че трябва да са точно обратните резултати,а именно там където се ползва [] оператора да е по-бавно,въпреки,че паметта е алокирана на едно място

Това всъщност показва, че компилатора на Ръст е доста добър.

Стига ве,и само заради branch prediction-а ли да прави такива разлики,забележи че долу ползва даже <= оператор,ако ползва само < още би трябвало да падне времето

Какво значение има дали ще е <= или <?

#21582 (ツ) saruman
Създадено на 13.12.2020, видяно: 1655 пъти.

Е как какво,първото ти прави < и след това ==,това са две операции,а второто само <

#21583 (ツ) |
Създадено на 13.12.2020, видяно: 1651 пъти.
saruman

Е как какво,първото ти прави < и след това ==,това са две операции,а второто само <

Струва ми се, че Иванушка Пъдаря ще ти се кара, че не знаеш асемблерските инструкции. :)

#21584 (ツ) saruman
Последно редактирано на 13.12.2020 от saruman, видяно: 1646 пъти.
|
saruman

Е как какво,първото ти прави < и след това ==,това са две операции,а второто само <

Струва ми се, че Иванушка Пъдаря ще ти се кара, че не знаеш асемблерските инструкции. :)

Мълча позорно,признавам

https://stackoverflow.com/questions/12135518/is-faster-than

По-важното е,че ако я нямаше тая тема,щях да си продължавам да си живея в заблуда,че едното е по-бързо от другото :(

#21586 (ツ) Дон Реба
Създадено на 13.12.2020, видяно: 1639 пъти.
saruman

Стига ве,и само заради branch prediction-а ли да прави такива разлики,забележи че долу ползва даже <= оператор,ако ползва само < още би трябвало да падне времето

да, само заради него е. обаче и на правец 16 дето няма конвеери мисля че "аритметичния" вариант ще е по-бърз, но няма да е с толкова много. ифа дори на платформа без конвеери монвеери е няколко операции и замяната му с аритметична операция (индексиране) още от фортранските времена си е била далавера. компилаторите от много отдавна като компилират switch гледат дали клоновете са последователни числа, и ако да компилират аритметично, без ифове.

#21590 (ツ) |
Последно редактирано на 13.12.2020 от |, видяно: 1632 пъти.

На мен това diff-1 изобщо не ми харесва помеже може да доведе до array under/overflow. Ако разбирач правилно, че usize e unsigned, аз бих го написал като ... mut prev = 1 извън цикъла, и в цикъла prev = i + 1, индекса diff

П.П. всъщност най-добре е просто масива да се направи с 4 елемента.

#21591 (ツ) Дон Реба
Създадено на 13.12.2020, видяно: 1629 пъти.
|

На мен това diff-1 изобщо не ми харесва помеже може да доведе до array under/overflow.

ами не може, ако можеше ръста няма да го компилира. и да, точно защото е без знак, ако е негативно ще стане просто голямо число.

#21592 (ツ) |
Създадено на 13.12.2020, видяно: 1627 пъти.
Дон Реба
|

На мен това diff-1 изобщо не ми харесва помеже може да доведе до array under/overflow.

ами не може, ако можеше ръста няма да го компилира. и да, точно защото е без знак, ако е негативно ще стане просто голямо число.

затова съм написал under/overflow.

#21593 (ツ) Дон Реба
Създадено на 13.12.2020, видяно: 1625 пъти.

деа, май си прав, какво става при нула? защо ръста го позволява?

#21601 (ツ) Courvoisier
Създадено на 13.12.2020, видяно: 1604 пъти.
#21614 (ツ) |
Създадено на 13.12.2020, видяно: 1585 пъти.
Дон Реба

деа, май си прав, какво става при нула? защо ръста го позволява?

Нямам идея, не трябва ли да го позволява?

#21631 (ツ) Дон Реба
Създадено на 13.12.2020, видяно: 1569 пъти.

не трябва, идеята е че ръста по време на компилация трябва да го види като грешка, но не го вижда, а и програмата не гърми, така че нещо недоглеждам

#21632 (ツ) |
Последно редактирано на 13.12.2020 от |, видяно: 1567 пъти.
Дон Реба

не трябва, идеята е че ръста по време на компилация трябва да го види като грешка, но не го вижда, а и програмата не гърми, така че нещо недоглеждам

Хмм, толкова ли му е добър статичния анализ? Чувал съм, че Ръст се опитва да осигури някаква коректност at compile time, но е ясно и че не всичко може да се направи тогава.

Това означава ли, че всеки достъп до елемент на масив трябва да е guard-нат от екплицитна проверка дали индекса е в размерите на масива?

#21636 (ツ) ФейкПрофил
Създадено на 13.12.2020, видяно: 1556 пъти.

Масивите имат bound checks. Ако индекса е извън границите на масива ще се паникьоса и умре в рънтайм. Обаче ако LLVM се усети, че индекса винаги ще е в границата на масива, то тогава ще махне bounds check-a като dead code.

Отделно debug билдовете се инструментират от компилатора с проверки за over/under flow. Което ти позволява да хванеш разни тъпи грешки. Обаче в release mode ги няма тези проверки, защото доста забавят.

0 1 2

Защо така ?
1

AsmBB v3.0 (check-in: a316dab8b98d07d9); SQLite v3.42.0 (check-in: 831d0fb2836b71c9);
©2016..2023 John Found; Licensed under EUPL. Powered by Assembly language Created with Fresh IDE