CPP 5SE осень 2017 — различия между версиями
Материал из SEWiki
Nikulin (обсуждение | вклад) |
Nikulin (обсуждение | вклад) |
||
(не показано 5 промежуточных версий этого же участника) | |||
Строка 12: | Строка 12: | ||
[https://ru.wikipedia.org/wiki/Постулат_Бертрана Теорема, для написания функции rehash к первой домашке] | [https://ru.wikipedia.org/wiki/Постулат_Бертрана Теорема, для написания функции rehash к первой домашке] | ||
+ | |||
+ | ----- | ||
+ | |||
+ | === Хаки === | ||
+ | |||
+ | Далее будут описаны <<Вредные советы>>. Никогда не делайте так в реальной жизни. | ||
+ | Если где-то на работе или в лабе вы сделаете так и сошлетесь на меня, то меня будут | ||
+ | ненавидеть (пожалуйста не надо так). К тому же ряд утверждений спорны, поэтому | ||
+ | буду только рад обсуждению и спорам по делу. | ||
+ | |||
+ | # Вызов функции - дорого. | ||
+ | #: пишите весь код в одной функции, желательно в мэйне (main function) | ||
+ | #: Да, это невозможно будет читать, но ведь все равно никто не будет читать ваш код. | ||
+ | # I/O - это дорого | ||
+ | #: постарайтесь считать весь входной поток за один раз в stringstream, а потом работать с ним | ||
+ | #: stringstream, в отличии от потоков ввода/вывода уже находится в памяти процесса. Обращение к нему бесплатно. В то же время каждый i/o - это системный вызов, смена контекста туда и обратно и потенциально снятие с процессора. | ||
+ | #: тоже самое с выводом | ||
+ | # выделение памяти - это дорого | ||
+ | #: некоторые структуры данных, например vector, позволяет заранее зарезервировать нужное количество памяти | ||
+ | #: некоторые структуры данных, которые сей интерфейс не предоставляют, могут его проэмулировать, если последовательно вызвать resize() -> clear() | ||
+ | #: для некоторых структур данных этот хак вообще не имеет смысла (например деревья). Для них так делать не надо | ||
+ | # O(n log(n)) может быть разным | ||
+ | #: Если последовательно добавлять даннные в set, то на это потребуется O(n log(n)) времени, и в итоге вы получите отсортированный контейнер. Так вот: это дорого. | ||
+ | #: Если вам просто нужно один раз отсортировать контейнер, то используйте std::sort(v.begjn(), v.end()) над вектором. Это будет намного быстрее. Да и доступ потом будет бытрее даже ассимптотически | ||
+ | # Глобальные переменные - это странный предмет, ингда дорого, иногда - нет | ||
+ | #: Для меня это было неожиданностью, но применение глобальных переменных вместо локальных может уменьшить скорость более чем в 2 раза. | ||
+ | #: Для меня это было неожиданностью, но в некоторых случаях применения глобал переменных увеличивает скорость | ||
+ | # Размер имеет значение | ||
+ | #: Потенциально работа с short будет быстрее, чем работа с int (но не факт) | ||
+ | #: Применение double вместо float в 32-битном компиляторе реально медленней (вроде раза в 3) | ||
+ | #: Предыдущий пункт касается также и long vs int | ||
+ | #: для 64 битного компилятора вроде как одинаково | ||
+ | #: Спорно, но 32-битный компилятор может породить более быстрый код (если не использовать long и double) |
Текущая версия на 00:19, 10 ноября 2017
Преподаватель: Валерий Михайлович Лесин valery.lesin@gmail.com
Голосование за темы на семинарах
Теорема, для написания функции rehash к первой домашке
Хаки
Далее будут описаны <<Вредные советы>>. Никогда не делайте так в реальной жизни. Если где-то на работе или в лабе вы сделаете так и сошлетесь на меня, то меня будут ненавидеть (пожалуйста не надо так). К тому же ряд утверждений спорны, поэтому буду только рад обсуждению и спорам по делу.
- Вызов функции - дорого.
- пишите весь код в одной функции, желательно в мэйне (main function)
- Да, это невозможно будет читать, но ведь все равно никто не будет читать ваш код.
- I/O - это дорого
- постарайтесь считать весь входной поток за один раз в stringstream, а потом работать с ним
- stringstream, в отличии от потоков ввода/вывода уже находится в памяти процесса. Обращение к нему бесплатно. В то же время каждый i/o - это системный вызов, смена контекста туда и обратно и потенциально снятие с процессора.
- тоже самое с выводом
- выделение памяти - это дорого
- некоторые структуры данных, например vector, позволяет заранее зарезервировать нужное количество памяти
- некоторые структуры данных, которые сей интерфейс не предоставляют, могут его проэмулировать, если последовательно вызвать resize() -> clear()
- для некоторых структур данных этот хак вообще не имеет смысла (например деревья). Для них так делать не надо
- O(n log(n)) может быть разным
- Если последовательно добавлять даннные в set, то на это потребуется O(n log(n)) времени, и в итоге вы получите отсортированный контейнер. Так вот: это дорого.
- Если вам просто нужно один раз отсортировать контейнер, то используйте std::sort(v.begjn(), v.end()) над вектором. Это будет намного быстрее. Да и доступ потом будет бытрее даже ассимптотически
- Глобальные переменные - это странный предмет, ингда дорого, иногда - нет
- Для меня это было неожиданностью, но применение глобальных переменных вместо локальных может уменьшить скорость более чем в 2 раза.
- Для меня это было неожиданностью, но в некоторых случаях применения глобал переменных увеличивает скорость
- Размер имеет значение
- Потенциально работа с short будет быстрее, чем работа с int (но не факт)
- Применение double вместо float в 32-битном компиляторе реально медленней (вроде раза в 3)
- Предыдущий пункт касается также и long vs int
- для 64 битного компилятора вроде как одинаково
- Спорно, но 32-битный компилятор может породить более быстрый код (если не использовать long и double)