LINUX.ORG.RU
ФорумTalks

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

 ,


0

2

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


Ответ на: комментарий от vbr

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

Я лично сравнивал работу со строками в луа разных версий и компактными версиями ява-скрипта например и питоном. Разница радикальная, особенно на больших строках. Это по сути единственное, где луа медленнее. Во всем остальном он лучше.

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

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

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

Да знаю я эти структуры и разницу работы с ними. Но нет, не исчезнут. В прогрмммировании не существует магических способов. И нет, в яваскрипте даже в компактных его версиях работа с строками в разы быстрее. Особенно с длинными строками.

Я три года только с этим и работаю же, наэкспериментировался.

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

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

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

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

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

Приятно видеть, адепты Коли Вирта подтянулись.

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

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

А ещё лучше, если этим занимаются другие и до того, как приложение написано. Вот только дорого это, да и вообще V&V специалистов не просто найти. Берут кого попало, потому что скучная кропотливая работа.

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

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

Хотя да, тесты в какой то мере помогают. Как и обмазывание отловом крайних случаев.

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

Нет. Не согласен. Подход Интел «пусть пользователи тестируют» уже привёл её один раз к тому, что чуть не превратились в отдел Броадком. Да и сейчас ничего еще не кончилось, народ бежит.

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

Да не, я за баланс. Тестирование - это охренительная штука. Оно нужно. Но нет смысла упарываться в него во вред остальному.

Я лично видел два радикально разных по подходу проекта. В одном тестирование отрицали как класс. Сервер падал бывало несколько десятков раз в сутки. Зато новое внедряли реактивно. Кучи нового, инновационного…криво работающего.

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

И тот и тот подход - говно.

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

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

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

и в три. Тестирование и проверка соответствия спецификации - намног

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

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

Это я как раз и называю «подход Интел» - сокращение издержек за счёт верификации и тестирования. Результат нам известен. Менеджеров надо было сокращать, а не инженеров. Теперь пусть хлебают из сита ложечкой.

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

Там всё очень плохо. Государство долю выкупило, чтобы не распродали по частям. Такое было когда-то с Дженерал Моторз или Крей.

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

да и то что он бытр почти как сишка на самом деле.

Вполне понимаю, сам интерпретируемый язык когда-то юзал (AutoIt3). Функции написаны на С++, соответственно если скормить регулярному выражению твои 40 тыс. строк, он их обработает со скоростью компилируемого языка. Поэтому программы написанные на нём не выглядят тормознутыми, а размер проги начинается от 240кб на старых версиях, до 700 кб на новых.

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

А тут весь интерпретатор 500кб, к слову.

https://s6.iimage.su/s/16/gpbHbBOxa9owsCsVie6EcMtoaUQOjChzzXPUJhLcH.jpg

Вот сделал небольшой концептуальный вандализм. Если не двигаешься в игре, появляется пучок и заплетает интерфейс паутиной, съедает элементы интерфеса. Сложный выбор маршрутов по А*, естественное поведение, ручные анимации. Все в 200+кб кода уместилось плюс минус.

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

А тут весь интерпретатор 500кб, к слову.

Внешний? Вот только что тему читал на форуме PureBasic как чел пытается интерпретатор луа воткнуть в исполняемый файл, чтобы было более автономно. AutoIt3 кстати так и делает, он вставляет себя же со скриптом в исполняемый файл применяет собственное сжатие и допускает сжатие другими пакерами.

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

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

Неужели второй и если да, то почему?

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

Там обсуждено дальше. Потому что иногда важна не скорость, а компактность хранения данных. Иногда приходится шифровать данные, например использовать вместо ников, которые могут быть на латинице и кириллице до 22 байт длиной, их трехсимвольные айдишники в 85й системе счисления. Хранить данные не в массиве или хэшбтаблице ключ-занчение, а в сложной многомерной таблице: ключ-значение1значение2..значение100.

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

Ну почему же. Оно чисто технически работает. Просто при переполнении все данные обнулятся. У мея до первой поломки данные собирались больше 2 лет. Мало юзеров было.

А еще иногда можно сделать выбо в пользу скорости разработки, читаемости, фич. Например у меня был установщик аддонов на раст. Бинарник размером 7,5мб и потреблял озу метров 30 чтоли. Но я его заменил на установщик на электроне. Только бинарник 60-100мб. А озу выжирает несколько сотен метров. Зато там красиво, анимации готовые. Ну и цпу меньше жрет.

Все зависит от задачи и целей. Да много от чего. От особенностей проекта. Кучи переменных, которые сразу не учесть.

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

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

Путём изменения алгоритма - до 5 раз.

И до 50 и до 500 раз. Я такое проходил поэтому не голословно говорю.

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

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

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

Конечно, если один алгоритм имеет масштабирование для размера задачи n как alog(n), а второй как bexp(n), то несложно найти такое n, где второй медленее первого и в 50, и в 500, и в 5000 раз. Но вот проблема. Обычно a много больше b. И второе, обычно n разумное на практике, а не 10 миллионов миллиардов. Поэтому алгоритмы второго типа настолько же часто используются, насколько и первого. Вот только не всегда для нужных n.

Это всё тривиальные факты. Но может кому-то и будет полезно.

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

Я тут потестировал.

-rwxr-xr-x 1 diver diver  17102 авг 17 00:05 my_program
-rwxr-xr-x 1 diver diver 451183 авг 17 00:06 my_program1
diver ~/Games/wc/CircleL/Interface/AddOns/NSQC3/111/build/1 % file my_program                                          0:06:42
my_program: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=41eb1506004de07a84ba6b1ca8f727631cb53251, for GNU/Linux 3.2.0, not stripped

Вот я сделал бинарник с динамической линковкой. Первое - print(‘hello’), второе - полноценный скрипт на 424кб. При динамической линковке получаем бинарник практически такого же размера. Добавляется 17кб служебной инфы.

Можно конечно еще сжать, способы есть, но смысла не вижу.

При статической линковке служебой инфы где то 1.3мб:

-rwxr-xr-x 1 diver diver 1790175 авг 17 00:23 my_program_static3
my_program_static3: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=77453f2627aea3c1cbadfe17a08b8e12be220652, for GNU/Linux 3.2.0, stripped

В итоге мы получаем бинарник 1.7мб. Где 423 кб собственное кода, зато работает без внешних интерпретаторов. Вполне приемлемо, как по мне.

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

Ну почему же. Оно чисто технически работает. Просто при переполнении все данные обнулятся.

Это даже «чисто технически работает» нельзя назвать так как уже известно когда оно делает плохо.

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

На самом деле можно. Есть вариант очистки таблиц, например. Вот я в итоге стал хранить не всю историю чата, а только последние 10 тысяч соощений. Где то на недельку этого хватает.

Можно очищать таблицы ушедших игроков или которые давно не пользовались возможностями или архивировать. Это просто возможнсти и алгоритмы. Ты сам решаешь как их использовать.

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

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

Полностью поддерживаю!

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

Это если начальный алгоритм исаользуется не по предназначению.

Бывает как раз что начальный полностью верный с точки зрения теории, а вот несовсем правильный, но не неверный, оказывается сильно выгоднее.

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

Бывает как раз что начальный полностью верный с точки зрения теории, а вот несовсем правильный, но не неверный, оказывается сильно выгоднее.

Сложный текст, но я понял, что вы хотели сказать. Всё бывает. Я вообще не сильно понимаю, что ТС спрашивает, поскольку очень абстрактно проблема сформулирована «Смотрите ли вы не сложность алгоритмов, которые реализуете?» Да, конечно, и что?

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

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

А вы их как очищаете, по крону?

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

А зачем? Пишем в массив новую строку в конец и если количество строк больше 10000, удаляем первую.

При сложной структуре массива алгоритм чуть сложнее, но не сильно.

У меня свой отдельный класс работы с базами данных. Там можно задать экземпляру ограничения. Количества строк, количество сообщений в строках итд. А он уже сам обработает как надо.

Ну и общие бэкапы, конечно по крону. Жить без бэкапов нельзя. Но это уже подстраховка, которая нужна редко.

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

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

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

До ассемблера ещё дожить надо. И преобразование от исходного кода до машинного кода может порой сильно удивлять. Как в хорошую, так и в плохую сторону.

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

Про Эльбрус я ничего не знаю. Но вообще процессоры попроще, вроде слабеньких ARM, там с циклами всё довольно просто. Грубо говоря конвеер на три инструкции. Пока выполнение идёт линейно - одна инструкция = 1 цикл. Если прыжок, то 2 инструкции пропускаем. Я как-то даже писал sleep с наносекундной точностью (в пределах скорости процессора) из спортивного интереса - работало.

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

А зачем? Пишем в массив новую строку в конец и если количество строк больше 10000, удаляем первую.

Понял, т.е. каждый раз при записи новой.

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

Понял, т.е. каждый раз при записи новой.

Если в массиве строки одиночные, то да. А если в каждой строке по 10 сообщений, то каждое 10е сообщение. Это простейшее.

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

Неа. Представь что у меня каждая строка массива это сто строк чата. Я проверяю: Если это тысячная строка, то: Если в строке меньше 100 сообщений, то пишем в эту строку.

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

То есть в этом случае удаление первой строки происходит каждую сотую запись.

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

Но вообще процессоры попроще, вроде слабеньких ARM, там с циклами всё довольно просто. Грубо говоря конвеер на три инструкции.

Когда-то в бытность моего детства работали мы вместе с Гири Чуккапалли, он в это время в Броадком был, над разработкой первого SVE процессора. Поверьте, разработать аккуратный симулятор не так просто. И не сделаете вы FMA за три такта на конвейере, минимум за пять. И умножать за три такта ох как попрыгать надо. А только окно выборки команд заполнилось, и оппа, попробуйте предсказать размер пузыря. А если операция с памятью, то приплыли.

Кстати, сейчас вы этот процессор знаете под именем Grace компании Nvidia. А Гири до сих пор Армы штампует, теперь уже для Grace-Hopper или Grace-Broadwell. Grace там практически тот же, что и Broadcom Vulcan.

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

И преобразование от исходного кода до машинного кода может порой сильно удивлять. Как в хорошую, так и в плохую сторону.

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

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

А про Эльбрус я сказал, потому что там пионеры с горящими глазами, туда лучше не соваться. Они уже всё знают.

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

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

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

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

VIT ★★★
()
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)