Здравствуйте, пффф, Вы писали:
п> п>> п>> R>Поэтому не нужно так делать Можно сравнивать ничего не извлекая.
п> п>> R>Ты же знаешь, что у строк есть индексный доступ? Ну?
п> п>> И?
п> R>Чего и? Напряги мозгу.
п> Хочу от тебя узнать правильный ответ, самому не додуматься
Сравниваем максимум три символа с указанных позиций ничего не извлекая:
Здравствуйте, rudzuk, Вы писали:
п>> R>Чего и? Напряги мозгу.
п>> Хочу от тебя узнать правильный ответ, самому не додуматься
R>Сравниваем максимум три символа с указанных позиций ничего не извлекая: R>
Для получения символа в строке есть специальные функции, прикинь. Даже если делать "в лоб" и искать от начала строки, то на миллион поисков по имени файла длинной 15 символов + точка + 3 символа на расширение затрачивается всего около 30 мсек. на древнем железе. Если же подойти к вопросу творчески, сразу проверить FileName[Length(FileName) — 3] = '.' , и если это не точка то искать начиная с конца, то времени будет затрачено и того меньше. Короче, не парь меня своими прематурными переживаниями в вечер воскресения ночь понедельника.
Здравствуйте, rudzuk, Вы писали:
п>> Откуда нам известны lExtPos, rExtPos?
R>Для получения символа в строке есть специальные функции, прикинь.
R>Даже если делать "в лоб" и искать от начала строки, то на миллион поисков по имени файла длинной 15 символов + точка + 3 символа на расширение затрачивается всего около 30 мсек. на древнем железе.
Надо искать не "в лоб", а с конца строки. А это ещё один удар по производительности.
И надо ещё искать положение разделителя частей пути. Потому что, внезапно, файлы могут не иметь расширения, а каталоги — как раз иметь. Или файл будет какой-нибудь .tar.bz с двойным расширением.
И теперь умножаем это на удвоенное количество сравнений при сортировке (удвоенное — потому что для обоих операндов надо искать). У твоих пользователей появляется реальный шанс не дожить до получения результата.
R>Если же подойти к вопросу творчески, сразу проверить FileName[Length(FileName) — 3] = '.' , и если это не точка то искать начиная с конца, то времени будет затрачено и того меньше.
Ха-ха, у тебя расширения имени файла всегда только трёхсимвольные?
R>Короче, не парь меня своими прематурными переживаниями в вечер воскресения ночь понедельника.
Мне жалко пользователей твоего софта.
И да, ожидания не прематурные, а вполне реальные. Я делал много разных сортировок строк, в том числе и сортировка строк с учетом числовых значений в этих строках. И да, предварительное извлечение всей необходимой для сортировки информации очень сказывается на производительности.
А реально ли извлекать части из сортируемых строк, делать ли для них что-то типа string_view или сохранять индексы — это дело десятое.
Здравствуйте, пффф, Вы писали:
п> R>Даже если делать "в лоб" и искать от начала строки, то на миллион поисков по имени файла длинной 15 символов + точка + 3 символа на расширение затрачивается всего около 30 мсек. на древнем железе.
п> Надо искать не "в лоб", а с конца строки.
Ты умница. Внимательно читал. Жаль, что не все понял.
п> И надо ещё искать положение разделителя частей пути.
А кто сказал, что имя файла включает полный путь? Оставь свои выдумки.
п> Или файл будет какой-нибудь .tar.bz с двойным расширением.
А вот это уж вопрос интерпретации, что считать расширением. Потому что, например, файл system.sysutils.pas имеет одно расширение.
п> И теперь умножаем это на удвоенное количество сравнений при сортировке (удвоенное — потому что для обоих операндов надо искать). У твоих пользователей появляется реальный шанс не дожить до получения результата.
30 мсек. на 1млн. поисков самым неоптимальным способом. Але.
п> R>Если же подойти к вопросу творчески, сразу проверить FileName[Length(FileName) — 3] = '.' , и если это не точка то искать начиная с конца, то времени будет затрачено и того меньше.
п> Ха-ха, у тебя расширения имени файла всегда только трёхсимвольные?
864817 — общее количество файлов на моей рабочей винде.
520468 — количество файлов с трехсимвольным расширением.
Итого, 60% файлов имеют трехсимвольное расширение. Вот и подумай.
п> И да, ожидания не прематурные, а вполне реальные. Я делал много разных сортировок строк, в том числе и сортировка строк с учетом числовых значений в этих строках. И да, предварительное извлечение всей необходимой для сортировки информации очень сказывается на производительности.
Да нет, ты именно прематурщик в чистом виде. Напридумывал условий, сам с собой поспорил, сам себя убедил. Без цифр, без замеров, без ничего. И весь такой прошаренный, оптимальный весь. Это у сишников болезнь такая, я в курсе. А как до дела доходит, так начинается игра в догонялки в коричневых штанах
Это не я прематурщик, это ты — тяпляпщик.
R>Итого, 60% файлов имеют трехсимвольное расширение. Вот и подумай.
Выкинуть или неправильно обработать 40% исходных данных — это надо постараться
R>Да нет, ты именно прематурщик в чистом виде. Напридумывал условий, сам с собой поспорил, сам себя убедил. Без цифр, без замеров, без ничего. И весь такой прошаренный, оптимальный весь. Это у сишников болезнь такая, я в курсе. А как до дела доходит, так начинается игра в догонялки в коричневых штанах
То-то на дельфях ваших ничего годного так и не написали в значимом количестве. У вас на реальных данных всё просто не работает. Ну, это конечно если вы не используете готовые компоненты. Компоненты обычно пишут люди достаточно квалифицированные. А вот то, что дельфисты пишут сами — это полный трешак.
ЗЫ Да, ЗеБат я видел, я даже Дос Навигатор видел. И Миднайт Командер тоже видел. Это топ уровень дельфячников
Здравствуйте, пффф, Вы писали:
п> R>Итого, 60% файлов имеют трехсимвольное расширение. Вот и подумай.
п> Выкинуть или неправильно обработать 40% исходных данных — это надо постараться
Что, читал, но у тебя не получилось? Пытайся еще. Старайся лучше.
п> R>Да нет, ты именно прематурщик в чистом виде. Напридумывал условий, сам с собой поспорил, сам себя убедил. Без цифр, без замеров, без ничего. И весь такой прошаренный, оптимальный весь. Это у сишников болезнь такая, я в курсе. А как до дела доходит, так начинается игра в догонялки в коричневых штанах
п> То-то на дельфях ваших ничего годного так и не написали в значимом количестве. У вас на реальных данных всё просто не работает. Ну, это конечно если вы не используете готовые компоненты. Компоненты обычно пишут люди достаточно квалифицированные. А вот то, что дельфисты пишут сами — это полный трешак.
На наших дельфях процессинги ОПСОСов работают, а ты иди утечки памяти ищи, оптимальный оптимизатор.
Здравствуйте, rudzuk, Вы писали: R>Просто пропустили наследование в TGAdvancedList. В комментарии оно есть, а в декларации пропущено.
Не вполне понятно, что будет написано в декларации. В комментарии упомянуто, что нужно придерживаться некоторой конвенции именования, но я не понимаю, какой. R>Да, но когда генериков нет это хороший вариант.
С этим я не спорю.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, пффф, Вы писали: П>Таки это лучше сначала на компоненты разобрать, а потом сортировать. Если при каждом сравнении извлекать часть, и потом её сравнивать, результат к пенсии получишь
Вообще-то, всё как раз наоборот.
"Разбор на компоненты" означает выделение памяти. Оно стоит дорого, что в нативном коде, что в среде с GС. В первом варианте мы сразу получаем штраф за выделение/освобождение, во втором — увеличиваем нагрузку на GC.
Лучший способ сортировки — это когда у нас есть специализированная функция, реализующая некоторый алгоритм сортировки (скорее всего — частично заинлайненная, чтобы в "листьевые" вызовы вообще не были вызовами). В эту функцию сразу должен быть встроен предикат сравнения с zero-copy. Никаких многкратных проходов вида "вот тут я разбираю path на запчасти", "а вот тут я из него выделяю нужный мне компонент", "а вот теперь я сортирую результат вот таким алгоритмом" не надо — если, конечно, хочется получить результат до пенсии.
В стародавние времена такое писали руками и очень гордились вылизанностью "до такта".
Но такой подход крайне трудоёмок, и в него тяжело вносить правки (т.к. логика сравнений и логика выбора элементов для сравнения перемешаны).
Поэтому хочется собирать этот алгоритм из кусочков, а всё это встраивание и оптимизацию делегировать компилятору, который не устаёт и не ошибается.
Наилучшие результаты тут будут у C++, который умеет инлайнить примерно всё, включая замыкания. Поэтому на нём компактно написанный код превратится в отлично оптимизированный целевой код без лишних копирований.
Неплохие результаты будут у Java, которая умеет делать спекулятивный инлайнинг и escape-analysis, при условии, что рассматриваемый код влезает в ограничения JIT.
Приемлемые результаты будут у C#, где отсутствие escape analysis компенсируется наличием value-типов, но идиотский дизайн делегатов мешает JIT-у оптимизироваться.
Достижение сравнимого с C++ результата возможно в библиотеках, которые злоупотребляют ленивостью и порождают байт-код самостоятельно.
Но самый стрёмный результат будет как раз на наивно-нативных языках вроде Pascal, где программист будет действовать именно так, как вы написали — перекладывать данные из одной структуры в другую.
Асимптотика, конечно, будет та же самая, но на мало-мальски сложной задаче код сольёт приличным реализациям в разы.
Ещё заметнее разница будет там, где возможен ранний выход — например, если мы делаем не сортировку или агрегацию, а поиск.
Тогда энергичная трансформация данных сделает лишнюю работу, которая будет выброшена на следующем этапе конвеера вычислений.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S> Не вполне понятно, что будет написано в декларации. В комментарии упомянуто, что нужно придерживаться некоторой конвенции именования, но я не понимаю, какой.
TGAdvancedList = class(TGList)
Там еще ошибка с декларацией поля Items, которое объявлено статическим массивом, но задумано, как динамический.
Здравствуйте, rudzuk, Вы писали:
R>Здравствуйте, Sinclair, Вы писали:
S>> Не вполне понятно, что будет написано в декларации. В комментарии упомянуто, что нужно придерживаться некоторой конвенции именования, но я не понимаю, какой. R>
R>TGAdvancedList = class(TGList)
R>
Ага, то есть там типа просто делается двойная подстановка, и они ожидают получить на выходе что-то типа
unit AdvancedListInteger;
interface
uses
Classes;
type
TAdvancedListIndex = Integer; // specified to some exact type
TAdvancedListItem = Integer; // specified to some exact type
TListIndex = TAdvancedListIndex;
TListItem = TAdvancedListItem;
// TGList<TListIndex, TListItem> = class
TGList = class
Items: array[TListIndex] of TListItem;
procedure Add(Item: TListItem);
end;
// TGAdvancedList<TAdvancedListIndex, TAdvancedListItem> = class(TGList)
TGAdvancedList = class(TGList)
Capacity: TAdvancedListIndex;
end;
// TAdvancedListInteger<Integer, Integer> = class
TAdvancedListInteger = class(TGAdvancedList)
// Additional fields and methods can be added hereend;
implementation
procedure TGList.Add(Item: TListItem);
begin
SetLength(Items, Length(Items) + 1);
Items[Length(Items) - 1] := Item;
end;
end.
R>Там еще ошибка с декларацией поля Items, которое объявлено статическим массивом, но задумано, как динамический.
Спасибо. Да, выглядит как относительно работоспособный трюк. Хотя и несколько, гм, неудобный в повседневном использовании. Ах, если бы вы показали его мне году эдак в 97м!
В принципе, идеального языка не придумали — в шарпе мы аналогичных обстоятельствах применяем T4. Ну, то есть конкретно такой код унижаться не заставляет, но если хочется сделать, скажем, набор типов-генериков, которые отличаются только количеством аргументов, то лучший споссоб — примерно тот же, что и ваш.
(Всякие interface IResult<T> { T[] GetResult()}, interface IResult<T1, T1> { (T1[], T2[]) GetResult()} и т.п)
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, pva, Вы писали:
K>>Делфи (ну и билдер, конечно тоже) прекрасный язык и платформа (были лет 20 назад точно, сейчас — хз) и прекрасно интегрируется с сишными либами через DLL.
Скажу больше, удавалось (не без полухакеского подхода) писать Dll-ки на VC++ для использования в Delphi, именно с экспортом сишных классов в паскаль. Не просто экспортируемых функций.
Здравствуйте, Maniacal, Вы писали:
M>Здравствуйте, pva, Вы писали:
K>>>Делфи (ну и билдер, конечно тоже) прекрасный язык и платформа (были лет 20 назад точно, сейчас — хз) и прекрасно интегрируется с сишными либами через DLL.
M>Скажу больше, удавалось (не без полухакеского подхода) писать Dll-ки на VC++ для использования в Delphi, именно с экспортом сишных классов в паскаль. Не просто экспортируемых функций.
C использование интерфейсов (без COM даже) не должно быть каких-то сложностей если понимаешь что делаешь.
Здравствуйте, swame, Вы писали:
S>C использование интерфейсов (без COM даже) не должно быть каких-то сложностей если понимаешь что делаешь.
на стеке у VC++ один лишний параметр добавляется, так что пришлось колдовать. Уже точно не помню, но, вроде, возвращаемый функцией параметр для Дельфи это первый параметр функции на VC++ (смотрю сейчас свои старые исходники)
Здравствуйте, пффф, Вы писали:
П>ЗЫ Да, ЗеБат я видел, я даже Дос Навигатор видел. И Миднайт Командер тоже видел. Это топ уровень дельфячников
Дак в Дос Навигаторе встроенный асм чуть менее, чем везде. Но зато у него многозадачность есть. Поиск файлов одновременно с текстовым редактором работает.
Здравствуйте, Maniacal, Вы писали:
M>Здравствуйте, swame, Вы писали:
S>>C использование интерфейсов (без COM даже) не должно быть каких-то сложностей если понимаешь что делаешь.
M>на стеке у VC++ один лишний параметр добавляется, так что пришлось колдовать. Уже точно не помню, но, вроде, возвращаемый функцией параметр для Дельфи это первый параметр функции на VC++ (смотрю сейчас свои старые исходники)
Здравствуйте, vsb, Вы писали:
vsb>Здравствуйте, Sinclair, Вы писали:
S>>Далее, выбор Хейльсбергом Object Pascal в качестве языка сыграл с пользователями Delphi дурную шутку. Паскаль сам по себе прекрасно подходит для изучения алгоритмов; а вот писать на нём повторно используемые алгоритмы практически невозможно. Отсутствие обобщённых типов и перегрузки операторов приводило к тому, что алгоритм сортировки писал себе примерно каждый (либо сводил всё к существующим решениям). S>>В целом, по сравнению с примерно любым современным языком, Delphi очень сильно мешает писать сложные алгоритмы с меньшим количеством ошибок. Тупо нет нужных средств декомпозиции алгоритмов.
Все средства есть. мало людей которые умеют декомпозировать, т.к. из за низкого порога входа пришли формоклепатели и "DBA".
vsb>И в Go до недавнего времени и в Java до 5 версии не было генериков. И ничего — через interface{} / Object прекрасно все алгоритмы писались.
interface это уже обобщение начального уровня.
vsb>Я больше скажу — ни в Go, ни в Java у меня не было никакой необходимости писать какие-то обобщённые алгоритмы.
vsb>И я даже ещё больше скажу. Крамольную вещь. Те, кто любят писать обобщённые алгоритмы, как правило, тратят время впустую на ментальную гимнастику вместо того, чтобы решать проблемы. Поэтому ругать конкретно Pascal считаю некорректным. Нормальный язык, никак не ограничивающий программиста. И во многих отношениях на порядок лучше того же С++.
В простых программах можно обойтись без обобщений.
В сложных без них не обойтись.
Если смог написать большую программу "без обобщений" и гигантского дублирования кода то молодец, но обобщения там все равно есть.
Здравствуйте, swame, Вы писали:
M>>на стеке у VC++ один лишний параметр добавляется, так что пришлось колдовать. Уже точно не помню, но, вроде, возвращаемый функцией параметр для Дельфи это первый параметр функции на VC++ (смотрю сейчас свои старые исходники)
S>https://www.gunsmoker.ru/2019/06/developing-DLL-API.html
Да я уже навелосипедировал. Одно дело писать нормальные функции для экспорта, другое __cdecl VC++ в __stdcall Delphi преобразовывать.
На простейшем примере
В Дельфи это для импорта
function AttrAsObject(psAttr : PAttribute) : IObject; stdcall; external'Object.dll';