Нашли или выдавили из себя код, который нельзя назвать нормальным,
на который без улыбки не взглянешь?
Не торопитесь его удалять или рефакторить, — запостите его на
говнокод.ру, посмеёмся вместе!
f<char>::bad(char)+0, f<char>::bad(char)+3 и f<char>::bad(char)+d - три раза за итерацию лезет в память. Разумеется, подобный код сливает в тестах производительности. Есть решение лучше, чем локальные переменные заводить каждый раз?
Ну можно проверить чтоб вот в диапазон где продрачивается цикл while (b != e) *b++=v; не попадает диапазон адресов самой этой структуры, и тогда заоптимизировать на основе этого.
template<typename T> struct f final {
void bad(T v) noexcept { while (b != e) *b++=v; }
void good(T v) noexcept {
auto tb(b), te(e);
while (tb != te) *tb++=v;
b=tb;
e=te;
}
T* b, * e;
};
специализировать типом int, крестоговнокомпилятор не будет предполагать что он перепишет хуйней "while (b != e) *b++=v;" хуйню "T* b, * e;" в этой говноструктуре
Ну по-стандарту указатель на сhar может указывать на любую хуйню и переписывать ее. Если там char, крестоговняный компилятор предполагает что хуйня "*b++=v;" может переписать указатели "T* b, * e;" в самой структуре и поэтому дрочит память
7 An object shall have its stored value accessed only by an lvalue expression that has one of the following types:
(The intent of this list is to specify those circumstances in which an object may or may not be aliased. )
* a type compatible with the effective type of the object,
* a qualified version of a type compatible with the effective type of the object,
* a type that is the signed or unsigned type corresponding to the effective type of the object,
* a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object,
* an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or
* a character type.
Мой критерий прост: если код компилируется крестокомпилятором - значит это код на C++. А используется или нет какая-то std::kokoko дрисня - дело десятое
> Тоесть, смотрите, как ведет себя настоящий, состоявшийся, знающий себе цену программист? А он ведет себя очень просто: плюсы - говно, но и си - говно, кричит он громко, ничуть не смущаясь подходящих к нему слева - одептов плюсов, а справа - почетателей битоебского низкоуровневого язычка типа Си
Нет, указатель адрес - он не может работать для регистра, ибо у него нет адреса - это питушизм. Это работает только потому, что конпелятор это умеет. В реальном мире стек давно сдох.
Алиас явно и чётко показывает идею - входящий елемент - есть алиас исходящего, как ссылка в путих С++. А с указателем ты такую фигню не сделаешь - только указатель на указатель.
Аналогов биндов вообще нет, кроме того, что я наваял в первой портянке. Либо юзать структуры и питухуказатели, но это слишком тормазная питушня.
Поэтому алиасы и указатели совершенно разные вещи, а бинды и кастыли со структурами - тоже разные вещи, ибо кастыли со структурами - питушня.
Я могу писать быстрее и лучше на сишке - мне удобней. Мне для этого не надо как рядовому питушку осиливать Сишку.
Всё должно отражать всё - если твоей конпелятор написан как говно - он и оптимизировать будет как говно. И да, оптимизации не нужны я уже не помню где был тред, помоему на лоре.
Вобще для моего мегаязыка оптимизации не нужны, ибо оптимизации нужны для питухов - там будет удобная ручная предсказуемость, как в ассемблере.
В место питушских переменных - там буду переменные, который на самом деле по умолчанию безымянные регистры. Явный их биндинг на имена, явный ялиасинг. Никаких стеков и прочей ереси.
Никаких автовекторизаций циклов( которые в 50% дают деградацию, допустим гцц(и все другие конпеляторы) по умолчанию вместо стекового фпу года гинерят ссе код, который медленее фпушного и теряют 10-30% производительности.
Никаких разворачиваний циклов - нормальная автогинерациия кода в компилтайме, а не питушнян а шаблонах как в С++ и не ущербные макросы.
Истинный компилтайм - для кода не будет существовать разницы между рантаймом и компилтаймом. Будет рантайм во время конпеляции - код будет сам гинерить то, что ему нужно.
Ты пишешь char m[] = f(); в функции ты реализуешь заполнении массива, а конпелятор её исполняет. Нал оре был целый тред про constexp или как там его.
Никаких оптимизаций циклов, никакой питушни - ты либо сам умеешь писать нормально циклы - либо иди в С++. Там за тебя в 20% случаев конпелятор заменит питушню на for(i) for(j) for(k) - на нормальный цикл на указателях, который работает в 3раза быстрее.
И ещё масса всего - все эти оптимизации от бешенства с жиру - глянь на царский код, ему не нужны никакие оптимизации, кроме алиасинга( и то это из-за особенностей сишки).
> Любая ваша структура данных - это вариации на указателях
Это справедливо только для классической питушни с адресным пространством, а есть еще всякие data-flow архитектуры, в которых адресуемой памяти вообще нихуя нет. В частности, для dataflow архитектур (которые очень часто реализуются поверх FPGA) применяются свои особые языки https://habrahabr.ru/post/122479/ вот статья со швабры например.
Н-н-н-нооо позвольте, где здесь С++, j123123?!это же чистая сишка.
то тогда GCC соптимизирует в memset:
Именно поэтому я за нормальные функции, а не всякое говно
https://godbolt.org/z/Ne28Mq
Но код good vs bad и так неэквивалентен.
Т.к. j123123 возможно привык жить в однопоточном мирке.
В случае bad ему явно говорят: инкременти указатель в структуре на каждой итерации.
В случае good ему явно говорят: скопируй себе указатель, поитерируй и поменяй его в конце цикла.
Понимаю что в царском мире, где у процессора одно ядро, а потоки не нужны, оба случая кажутся эквивалентными.
Однако это не так, ибо в многопоточном коде различие СУЩЕСТВЕННОЕ.
Он именно в своём единственном треде ссыт затереть b или e во время записи в *b.
специализировать типом int, крестоговнокомпилятор не будет предполагать что он перепишет хуйней "while (b != e) *b++=v;" хуйню "T* b, * e;" в этой говноструктуре
6.5 Expressions
Но на ЛОРе правильно сказали. Это сишка.
Человек пытался писать на крестах как на сишке. Ну и получил. Ещё по-божески.
// Specialization: for char types we can use memset
(и это не шутка, там реально специализация через мемсет)
И оно будет так же криво оптимизироваться.
Арифметика указателей, структуры, сhar. Кресты здесь причём?
Если б я этот код запостил как код на Си, мне б сказали что тут template<typename T> а в Си такого нет.
template тут не при чём.
> Тоесть, смотрите, как ведет себя настоящий, состоявшийся, знающий себе цену программист? А он ведет себя очень просто: плюсы - говно, но и си - говно, кричит он громко, ничуть не смущаясь подходящих к нему слева - одептов плюсов, а справа - почетателей битоебского низкоуровневого язычка типа Си
Или там перепитушни много?
Алиас явно и чётко показывает идею - входящий елемент - есть алиас исходящего, как ссылка в путих С++. А с указателем ты такую фигню не сделаешь - только указатель на указатель.
Аналогов биндов вообще нет, кроме того, что я наваял в первой портянке. Либо юзать структуры и питухуказатели, но это слишком тормазная питушня.
Поэтому алиасы и указатели совершенно разные вещи, а бинды и кастыли со структурами - тоже разные вещи, ибо кастыли со структурами - питушня.
Всё должно отражать всё - если твоей конпелятор написан как говно - он и оптимизировать будет как говно. И да, оптимизации не нужны я уже не помню где был тред, помоему на лоре.
Вобще для моего мегаязыка оптимизации не нужны, ибо оптимизации нужны для питухов - там будет удобная ручная предсказуемость, как в ассемблере.
В место питушских переменных - там буду переменные, который на самом деле по умолчанию безымянные регистры. Явный их биндинг на имена, явный ялиасинг. Никаких стеков и прочей ереси.
Никаких автовекторизаций циклов( которые в 50% дают деградацию, допустим гцц(и все другие конпеляторы) по умолчанию вместо стекового фпу года гинерят ссе код, который медленее фпушного и теряют 10-30% производительности.
Никаких разворачиваний циклов - нормальная автогинерациия кода в компилтайме, а не питушнян а шаблонах как в С++ и не ущербные макросы.
Истинный компилтайм - для кода не будет существовать разницы между рантаймом и компилтаймом. Будет рантайм во время конпеляции - код будет сам гинерить то, что ему нужно.
Ты пишешь char m[] = f(); в функции ты реализуешь заполнении массива, а конпелятор её исполняет. Нал оре был целый тред про constexp или как там его.
Никаких оптимизаций циклов, никакой питушни - ты либо сам умеешь писать нормально циклы - либо иди в С++. Там за тебя в 20% случаев конпелятор заменит питушню на for(i) for(j) for(k) - на нормальный цикл на указателях, который работает в 3раза быстрее.
И ещё масса всего - все эти оптимизации от бешенства с жиру - глянь на царский код, ему не нужны никакие оптимизации, кроме алиасинга( и то это из-за особенностей сишки).
Это справедливо только для классической питушни с адресным пространством, а есть еще всякие data-flow архитектуры, в которых адресуемой памяти вообще нихуя нет. В частности, для dataflow архитектур (которые очень часто реализуются поверх FPGA) применяются свои особые языки https://habrahabr.ru/post/122479/ вот статья со швабры например.
человек-компилятор
человек-отладчик
человек-дизассемблер
человек-интерпретатор