<bgdev />free

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

Защо така ?
1

0 1 2

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

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

Вариант 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.202018594eb30170b55fe60a1d1fe872f7d160c
#21575 (ツ) saruman
Последно редактирано на 13.12.2020 от saruman, видяно: 2150 пъти.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

0 1 2

Защо така ?
1

AsmBB v3.0 (check-in: 7544654b24928b93); SQLite v3.47.0 (check-in: 03a9703e27c44437);
©2016..2024 John Found; Licensed under EUPL. Powered by Assembly language Created with Fresh IDE