LINUX.ORG.RU
ФорумTalks

Проверяете ли вы скорость алгоритма?

 ,


0

2

Есть ли у вас привычка при обсуждении функций проверять её скорость и устранять слабые места? Мне даже хотелось иметь какой-то датчик числа операций, то есть не временем определять качество алгоритма, а количеством произведённых операций, количеством проделанных шагов (мегафлопсов).


Ты хочешь lcov? По идее purebasic же умеет бэкендить в си?

imul ★★★★★
()

Только сложность алгоритма, временная или по памяти. Не то чтобы это прям привычка, скорее на автомате. Практически всегда сразу видно порядок.

Фактическое потребление ресурсов редко замеряю. Для меня гораздо важнее чистота и удобство поддержки кода. Замеры нужны, когда имеем дело с узкими горлышками — теми участками кода, которые обслуживают самую нагруженную часть вычислений.

Другими словами, преждевременные оптимизации — это вред.

> Мне даже хотелось иметь какой-то датчик числа операций . . .

Посмотри как устроены бенчи в Go [1].

[1]: https://dave.cheney.net/2013/06/30/how-to-write-benchmarks-in-go

kaldeon ★★
()
Последнее исправление: kaldeon (всего исправлений: 3)

Мне кажется, что эта кроличья нора очень глубока. Я не знаю, какую команду процессор считает за, условно, один такт, а какую за много тактов. Сильно зависит от компилятора/интерпретатора и процессора. Когда-то писал какую-то хрень на js на очень слабом ноуте. Другой техники тогда под рукой не было. Скорость ощущал непосредственно. Вот оно работало шустренько, но как только избавился от повторений, распихал всё по объектам, распределил красиво, тормоза ощутил сразу. По-идее, современные движки «агрессивно оптимизируют» это. Типа, разворачивают, дублируют, мелочь инлайнят, но это в теории. На практике, на оптимизацию сейчас всем плевать. Программа «Погода» в 11-винде жрёт от 500mb и более, до гига с лишнем (вчера прочитал статью). Ладошкой_по_лбу.

Я раньше думал – почему не отделить программу от интернета, чтоб вообще не заморачиваться с безопасностью и не терять быстродействие. Но кому это нужно? То что работает у тебя на компе никому не интересно и денег не приносит. Надо всех тянуть в сеть и подсаживать на вэб-услуги. Чтобы платили как за ЖКХ.

rechnick ★★★
()

Есть ли у вас привычка

Сейчас нету, а когда использовал МК серии 8051 для изделий жёсткого реального времени, то там нужно было считать с точностью до 1 такта.

quickquest ★★★★★
()

Прямо привычки нет. Но в нагруженном приложении hot-path через perf прогнать это база.

vazgen05 ★★★
()

Иногда выбор алгоритма и проверка его скорости, потребляемые ресурсы и тем более доработка - это не прихоть, не хобби, не вопрос желания, а жесткая необходимсть.

Тебе бы в ограниченных песочницах поработать.

LightDiver ★★★★★
()
Последнее исправление: LightDiver (всего исправлений: 1)

Что значит «при обсуждении»? И о каких конкретно функциях речь? Если речь про функции в языке программирования, то проверять их скорость надо не при обсуждении а при написании. Но далеко не всех, а только тех, которые имеют шансы оказаться где-то узким местом. Датчик числа операций тут не обязателен, можно её вызвать много раз и просто замерить время.

Если же речь про то, чтобы не писать заведомо плохие алгоритмы, то тут обычно всё без проверок сразу ясно. Ну например не надо использовать функцию strcat, она каждый раз заново считает длину первой строки, это явно лишнее действие.

firkax ★★★★★
()
Ответ на: комментарий от firkax

А вот не всегда заранее понятно что именно будет лучше без проверок. Иногда нужны тесты.

Да и иногда приходится стандартные инструменты готовые переписать.

LightDiver ★★★★★
()
Последнее исправление: LightDiver (всего исправлений: 1)

не проверяю до тех пор, пока не получу нагоняй от начальства. И даже когда я получу нагоняй, всё равно удастся выжать с моей стороны процентов 10%, а боттлнек всё равно в кривом регистровом интерфейсе китайского асика или ещё какой-нибудь параше

seiken ★★★★★
()

Только когда заказчик жалуется.

Aceler ★★★★★
()

Есть ли у вас привычка при обсуждении функций проверять её скорость и устранять слабые места?

Для меня это не привычка. Это моя работа. Вот только что такое «при обсуждении функций»? При каком обсуждении?

VIT ★★★
()

Привычки нет. Если не устраивает производительность всей программы или скрипта в результате — тогда производится поиск функции, которая «тормозит», и соответственно, её оптимизация. При непосредственно написании при этом, естественно, всегда есть в голове мысль о том, что надо чтобы не выжирало больше ресурсов, чем требуется, и желание (обычно успешно реализуемое) написать не лишь бы как, а адекватно. Но именно вот такого, чтобы каждую функцию потом проверять — такого нет — это ж жизни не хватит таким заниматься, особенно если прям заморочиться и оптимизировать «пока оптимизируется» до талого… Звучит как «преждевременная оптимизация».

CrX ★★★★★
()
Ответ на: комментарий от CrX

Вообще, если прям честно, то иногда «что-то такое находит», и я этим таки занимаюсь. Недавно вот, например, даже заморочился с тем, чтобы один очень востребованный (но всегда динамически генерируемый) json на одном сайте всегда укладывался в один пакет. Практического смысла в этом не было, просто вот для себя хотелось, а то он получался то в один, то в два… Толку ноль, но удовлетворение есть. То же самое бывает с функциями, иногда даже смотрю ассемблерные листинги, что там компилятор выдал. Но редко, и одёргиваю себя от такой фигни. И никому не советую. Воспринимаю это скорее как «баг» собственной прошивки, а не достоинство или что-то, что нужно перенимать другим.

CrX ★★★★★
()

Если это криптографическая функция то да, и они уже как правило бенчи имеют.

anonymous_sama ★★★★★
()
Ответ на: комментарий от VIT

Вот только что такое «при обсуждении функций»?

Потому что для себя очень часто уже знаешь какой способ кодирования будет быстрый, а вот в общении на форумах при обсуждении многие выкладывают свои варианты кода определённой задачи сразу понимаешь что это будет медленно работать и начинается соревнования по выжиманию наибольшей скорости. И за собой замечаю, что могу влезть со своей проверкой в чужие дебаты, потому что мне этот критерий важен, даже если происходит снижение читаемости кода. Ускоришь в 1000 раз и сразу это становится весомым аргументом.

AZJIO
() автор топика
Ответ на: комментарий от AZJIO

Так зависит от места и задачи. Иногда в 1000 раз медленнее - приемлемо.

У меня есть функция, которая с одним алгоритмом читает и записывает 40 тысяч строк за 0.03с, а если второй алгоритм, где то же самое происходит за 15-40 секунд. Угадай какой я использую.

LightDiver ★★★★★
()
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от LightDiver

Угадай какой я использую

Которая не хреначит это в памяти? Построчно чтение запись? И результат которой не нужно следить?
Ну я конечно же про те операции, в которых пользователь ждёт когда она закончится.

AZJIO
() автор топика
Последнее исправление: AZJIO (всего исправлений: 1)
Ответ на: комментарий от rechnick

Для начала нужно понять, что «жрет память» и «выполняет такты процессора» это все-таки разное. Наиболее оптимизированные программные решения как раз работают напрямую в памяти или на GPU (забивая быструю видеопамять) ну или вообще на специализированных ASIC’ах

Я раньше думал – почему не отделить программу от интернета, чтоб вообще не заморачиваться с безопасностью и не терять быстродействие. Но кому это нужно? То что работает у тебя на компе никому не интересно и денег не приносит. Надо всех тянуть в сеть и подсаживать на вэб-услуги

Опять же слишком узкий взгляд на вещи если мы говорим об веб-приложениях и оптимизации, то как раз сейчас большинство действий пытаются переложить на клиент, чтобы у него в браузере считалось. А сервер просто отдает собранный бандл в виде одного большого файла статикой или наоборот много мелких файлов, которые легко закэшировать.

anonymous_sama ★★★★★
()
Ответ на: комментарий от AZJIO

Не, память тут не при чем. У меня ограничения на хранение - конкретно на количество аргументов в функции, количество локальных функций и самое хреновое - количество ключей в таблице.

Я могу хранить 10 тысяч строк по одной строке, например и это будет 10 тысяч ключей, а могу хранить хранить позиционно по 10 сообщений в строке и доставать из строки. Так я сокращаю количество ключей в десять раз сразу. А могу в сто раз. Вот в сто раз я и сократил.

Да, медленно, но это приемлемо, потому что у меня выбор:

  1. Работает, но медленно

  2. К хренам падает в рандомный момент и вся база данных обнуляется

Скорость - не всегда хорошо.

LightDiver ★★★★★
()
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от LightDiver

К хренам падает в рандомный момент и вся база данных обнуляется

Скорость - не всегда хорошо.

Так это накожено в перемешку с ИИ и другими пользователями? Или сбойный модуль с ограничением ключей? Для меня если что-то падает, значит в коде косяк, скорость тут ни при чём. Если код правильный, он при любой скорости на выходе даст одно и тоже при любой частоте процессора.

AZJIO
() автор топика
Ответ на: комментарий от AZJIO

Это было накожено еще в году этак 2002-2004 плюс минус. Когда про ИИ особо даже в перспективе никто не слышал. Штатная работа системы, такие вот особенности песочницы.

Понимаешь, вопрос не в работе, а в способе хранения. А способ хранения влияет на скорость обработки.

Ты можешь взять более быстрый алгоритм и через * месяцев все рухнет. И это ошибка.

LightDiver ★★★★★
()
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от LightDiver

Ты можешь взять более быстрый алгоритм и через * месяцев все рухнет.

Тут ключевое слово «взять». Ну да, и такое было, берёшь чужой плаг/модуль и он падает и думаешь, есть ли смысл его использовать.

AZJIO
() автор топика
Ответ на: комментарий от AZJIO

Какой чужой модуль? Это чисто самописный код. Ты можешь взять алгоритм. Взять способ хранения. И вопрос тут вообще не в скорости - на нее часто по барабану. Никаких чужих модулей. Там в принципе нет готовых модулей. Ну почти.

Есть особенности языка, есть особенности версии языка, есть особенности инструмента языка, где одно и то же можно сделать разными способами.

Часто на скорость впринципе насрать, когда у тебя обработка 40 тысяч случаев происходит за 0.03 секунды, а работать тебе надо обычно с единицами и дестками строк. На память, к слову, еще больше насрать практически всегда.

А вот цпу - очень критично. Есть бесконечное число способов перегрузить цпу при простейших действиях. Причем сделать оптимальнее - охренеть нетривиальная задача.

Сравни насколько в 2000-2005 года выросли жесткие диски, ОЗУ и ЦПУ.

LightDiver ★★★★★
()
Последнее исправление: LightDiver (всего исправлений: 3)
Ответ на: комментарий от LightDiver

На память, к слову, еще больше насрать практически всегда.

А вот цпу - очень критично.

Зависит от задачи. Я вот как-то больше с ООМ сталкиваюсь.

bbc69
()
Ответ на: комментарий от bbc69

Зависит от задачи.

Я примерно это и писал - зависит от места применения и задачи в целом.

LightDiver ★★★★★
()

Только там, где критично. Потому что а зачем? Ну будет прошивка грузится 0.2 сек вместо 0.18, и что? А вот по прерыванию посчитать на DSP коэффициенты pid регулятора надо максимально быстро и всегда за одно и то же время, тут надо даже в ассемблерный код заглядывать.

aiqu6Ait ★★★★★
()
Ответ на: комментарий от LightDiver

К хренам падает в рандомный момент и вся база данных обнуляется

Это ж ты себе в ноги стреляешь. По стеку вызова пройди из error handler а и найди утечку

aiqu6Ait ★★★★★
()
Ответ на: комментарий от AZJIO

а вот в общении на форумах при обсуждении

Понятно.

Вообще в вычислительной математике есть такое понятие как «вычислительная сложность алгоритма». В программировании есть «накладные расходы на реализацию». При оптимизации сначала следует определить, что оптимизировать, сложность или расходы. Определение это зависит от начальных данных и типично используемых параметров.

Когда говорят «хочу ускорить в 1000 раз», причём серьёзно, а не для красивого словца, то один подход не поможет, нужно комплексное решение. Путём перекодирования можно достигать ускорений в 2-3 раза. Путём увеличения параллелизма одного компонента - в 10-100 раз. Путём увеличения числа компонентов в 10-100 раз. Путём изменения алгоритма - до 5 раз. Ясно, что цифры примерные, из опыта. Но я могу объяснить, как я получил ту или иную цифру.

VIT ★★★
()
Ответ на: комментарий от aiqu6Ait

Утечек нет, просто ограничение в 230 тысяч ключей.

LightDiver ★★★★★
()

Так как бизнес-логика иногда не предполагает сразу оптимальные алгоритмы JOIN, то сначала как получится, потом смотрю планы выполнения, потом оптимизирую.

Shadow ★★★★★
()
Ответ на: комментарий от AZJIO

WebView2

Что характерно, скорее всего это двойной буфер отрисованной канвы.

Shadow ★★★★★
()
Ответ на: комментарий от anonymous_sama

Опять же слишком узкий взгляд на вещи

Естественно я сужу со своей колокольни.

если мы говорим об веб-приложениях и оптимизации

Нет. В вэб-приложениях я делаю до 10% работы. И это максимум. И то, потому что ИИ. Буквально недавно в вэб-приложениях я делал 0,1% работы. И мне нафиг не впёрлась безопасность и закрывание дыр за счёт быстродействия компа.

rechnick ★★★
()
Ответ на: комментарий от LightDiver

Вот в сто раз я и сократил.

Ну так ты получается не алгоритмическую сложность уменьшил (условно O(n**2) а просто уменьшил n

cobold ★★★★★
()
Ответ на: комментарий от cobold

Так я не уменьшал. У меня алгоритмическая сложность абсолютно та же О(n). Просто работа с каждой строкой замедлена на два порядка.

Я даже больше скажу, чаще всего это О(1). Например, мне нужно найти 1051 сообщение. 1051 / 100 = 10.51 - это десятая строка. Мне не нужно проходить по всем строкам. Я сразу обращаюсь к 10 строке массива и точно знаю где там будет именно мое сообщение - оно там 1051 - (10 * 100) = пятьдесят первое.

Замедление, причем кратное тут возникет при работе с этими строками. Представь что тебе надо их менять. Ты не можешь просто писвоить строку номеру в массиве. Нужно: 1) Вырезать первую часть строки 2) Вырезать последнюю часть строки 3) Изменить нашу центральную 4) Склеить итоговую строку заново 5) Записать в номер в массиве.

LightDiver ★★★★★
()

Узнай про то что в линуксах есть perf

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 1)
Ответ на: комментарий от LightDiver

Нужно: 1) Вырезать первую часть строки 2) Вырезать последнюю часть строки 3) Изменить нашу центральную 4) Склеить итоговую строку заново 5) Записать в номер в массиве.

Доступа по указателю нет?

AZJIO
() автор топика
Ответ на: комментарий от AZJIO

Это луа. Он очень минималистичен. И работа со строками это его больное место.

Есть доступ по индексу массива максимум. Все. Сами строки неизменны. То есть, чтобы переписать строку, тебе нужно создать новую строку. А если тебе надо изменить строку, тебе нужно создать минимум четыре новые строки: часть до изменения, измененную часть, часть после изменения и итоговая склеенная единая строка.

LightDiver ★★★★★
()

при обсуждении

При каком ещё обсуждении? Изначально прикидываю порядок объёма данных и порядок сложности алгоритма. Где-то n*n сойдёт, а где-то нужно изначально сделать оптимально.

есть не временем определять качество алгоритма

А никто внешним временем и не определяет качество алгоритма. Всегда используется внутреннее время, т.е. операции, или такты.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

А никто внешним временем и не определяет качество алгоритма.

Точно! Внешним временем измеряют качество реализации.

VIT ★★★
()
Ответ на: комментарий от rechnick

Любой сайт в том числе и лор это веб-приложение. Понятно что лор далеко не эталон современных хороших практик, хоть и обновляется, но аудитория в большинстве случаев всегда ценится больше чем само приложение. Так что я сомневаюсь, что прям 10%

anonymous_sama ★★★★★
()
Ответ на: комментарий от anonymous_sama

В принципе, согласен с этим замечанием. Я постоянно что-то ищу. Это, конечно, программы делают. Однако, почти всё что мне нужно в интернете, можно реализовать без js. И это будут такие же приложения. Чуть более дубовые, да, зато безопасные. Онлайн-докс в браузере, конечно так не реализовать, я понимаю. Но даже это можно реализовать по-другому, не в браузере.

rechnick ★★★
()
Ответ на: комментарий от rechnick

Однако, почти всё что мне нужно в интернете, можно реализовать без js.

Концепция хорошая и я её поддерживаю, но есть два момента.

Первый, это свистелки и перделки. Ворде как они пользователю не нужны, вот только в реальности пользователи на это клюют.

Второй, это интересы третьих лиц. Надо же как-то собирать метрики и показывать рекламу.

Так что представить Интернет без ЖС я не могу. К моему большому сожалению.

bbc69
()
Ответ на: комментарий от bbc69

А кто мешает собирать метрики без js? Всё спокойно собирается. Браузер отправляет данные, формы, в том числе со скрытыми полями. К тому же, если бы развитие не свернуло в сторону развития js (свистелок-перделок), то работу с формами можно было бы значительно улучшить. Можно было бы доработать фреймы или сделать что-то подобное, но другое. Не вижу вообще никаких препятствий. Но кому-то понадобилось именно управлять твоим компом удалённо.

rechnick ★★★
()

У меня есть привычка писать код максимально оптимизированно. Но это плохая привычка, наследие олимпиадного прошлого. Дело в том, что без серьёзного профилирования, большинство подобных попыток превращается в лучшем случае в пустую трату времени и ненужное усложнение кода. А в худшем случае они могут просто напросто ухудшить производительность.

А серьёзным профилированием на ровном месте, конечно, заниматься никто не будет.

Современные компиляторы очень уж сложные. И «на глаз» предсказать производительность полученного машинного кода едва ли возможно.

Что нужно действительно делать - стараться выбирать оптимальные алгоритмы и структуры данных. Не писать алгоритмы сложностью O(N^2), если можно написать алгоритм сложностью O(NlogN). Даже если кажется, что N невелико, есть немаленький шанс, что это предположение окажется неверным. Это в принципе всё, что я бы советовал делать «по умолчанию». В остальном лучше озаботиться читаемым кодом и правильной архитектурой.

А когда приложение уже написано, то неплохо выделить месяц-другой, подготовить стенд, разработать сценарии нагрузочного тестирования, провести это самое тестирование, попробовать найти неудовлетворительную производительность, провести профилирование и оптимизацию уже на основе собранных данных, а не на глаз.

vbr ★★★★★
()
Последнее исправление: vbr (всего исправлений: 2)
Ответ на: комментарий от LightDiver

И работа со строками это его больное место.

Глупости. Нет никаких проблем при работе со строками в Lua. Там всё плюс-минус так же, как и в 9/10 других языках программирования.

Есть доступ по индексу массива максимум. Все. Сами строки неизменны.

Как в 9/10 других языков программирования.

То есть, чтобы переписать строку, тебе нужно создать новую строку. А если тебе надо изменить строку, тебе нужно создать минимум четыре новые строки: часть до изменения, измененную часть, часть после изменения и итоговая склеенная единая строка.

Я уже тебе писал, что надо использовать правильные структуры данных и все проблемы с производительностью магическим способом исчезнут. А твоя проблема будет ровно такой же и в питоне, и в жаве и в жаваскрипте и почти в любом другом языке программирования. Потому, что ты пользуешься языком неправильно, если у тебя производительность упирается в то, что ты постоянно колбасишь строки.

Обвинять инструмент в том, что он плохой, это популярная забава начинающих программистов. Но чаще всего проблема не в инструменте.

vbr ★★★★★
()
Последнее исправление: vbr (всего исправлений: 3)
Ответ на: комментарий от LightDiver

Все. Сами строки неизменны. То есть, чтобы переписать строку, тебе нужно создать новую строку. А если тебе надо изменить строку, тебе нужно создать минимум четыре новые строки:

Да уж, сразу изучать расхотелось. Я же только прочтя это начал гадать оптимизацию. Например если есть возможность отслеживать уменьшилась ли изменяемая часть строки, то сразу бы наклёвывался алгоритм записи в ту же строку по месту, а концовку по-байтно переписать сдвигом назад на величину уменьшения с вставкой Null в конце строки. А если увеличивается, то да концовку придётся буферизировать и перевыделять память для строки, но всё равно не создавать 4 переменных.

AZJIO
() автор топика
Ответ на: комментарий от LightDiver

Тебе бы в ограниченных песочницах поработать.

Хорошая рекомендация.

anc ★★★★★
()
Ответ на: комментарий от AZJIO

Ну, во-первых, язык имеет свои преимущества. Это и синтаксис и компактность самого интерпретатора - 500кб, да и то что он бытр почти как сишка на самом деле.

Ну и оптимизации есть. Например работа через t[#t + 1] быстрее, чем просто по номеру или через вставку в таблицу. А сборка через table.concat в зависимости от длины строки и версии языка дает ускорение х22-10000 по сравнению с обычной конкатенацией. Есть свои варианты работы, есть чего копать.

LightDiver ★★★★★
()
Вы не можете добавлять комментарии в эту тему: только для зарегистрированных, score>=50.