StrToInt на чистом паскале.

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

StrToInt на чистом паскале.

Сообщение Seenkao » 10.01.2022 18:19:54

Всем привет!

Потестируйте! :) Нужно выявлять ошибки в модуле. Чтоб им можно было пользоваться всем.

:idea: fast_StrToInt. :idea:

Зачем я это сделал? Функция быстрее работает на процессорах x86 чуть менее чем в два раза, на процессорах ARM быстрее, но я не помню насколько. А так как зачастую в программах используется перевод строковых значений в числа, то я думаю это немалый прирост в скорости.

плюсы (+): быстрее скорость работы, сделано на чистом паскале, подойдёт для любой платформы (в данном варианте рассматривается x86/ARM - 32/64 битные. Функция не вылетит с ошибкой! Результат функции булева переменная сообщающая успешен был перевод или нет, сам результат сохраняется в переменной (модуль ge_external_Utils).

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

примеры использования в программе. Сама функция geStrToInt в соседнем модуле. Пример сделан для разных систем Linux/Windows (возможно и MacOS но не совсем уверен в дефайнах).

Модуль предоставляет 16 пользовательских функций, основанных на трёх основных:
Код: Выделить всё
(* Rus: Ниже реализованы стандартные функции для перевода строк в число. Их
*      использование будет проще для большинства. Функции отмечены префиксом.
*      s_ - функции возвращают результат (если операция была неудачной, то
*      в результате вернётся ноль, но вы не узнаете, что операция была неудачной).
*      sc_ - результат функций удачная или не удачная была операция. Сам
*      конечный числовой результат считывайте в Value.
*)
// sc_ - speed + check
// s_ - speed (not check)

// Rus: Числа со знаком. Здесь нельзя использовать шестнадцатеричные, восьмеричные
//      и двоичные числа.
function sc_StrToShortInt(const Str: String; out Value: ShortInt): Boolean;    // byte
function s_StrToShortInt(const Str: String): ShortInt;                         // byte
function sc_StrToSmallInt(const Str: String; out Value: SmallInt): Boolean;    // word
function s_StrToSmallInt(const Str: String): SmallInt;                         // word
function sc_StrToInt(const Str: String; out Value: Integer): Boolean;
function s_StrToInt(const Str: String): Integer;
function sc_StrToInt64(const Str: String; out Value: Int64): Boolean;
function s_StrToInt64(const Str: String): Int64;

// Rus: Числа без знака. Эти функции могут использоваться и для шестнадцатеричныи
//      и восьмеричных и двоичных чисел.  Данные функции не должны содержать
//      ведущие нули для десятеричной системы счисления.
function sc_StrToByte(const Str: String; out Value: Byte): Boolean;
function s_StrToByte(const Str: String): Byte;
function sc_StrToWord(const Str: String; out Value: Word): Boolean;
function s_StrToWord(const Str: String): Word;
function sc_StrToLongWord(const Str: String; out Value: LongWord): Boolean;
function s_StrToLongWord(const Str: String): LongWord;
function sc_StrToQWord(const Str: String; out Value: QWord): Boolean;
function s_StrToQWord(const Str: String): QWord;   


В модуле три основных процедуры:
Код: Выделить всё
  function geStrToInt(const Str: String; out Value: maxIntVal; Size: LongWord = isInteger): Boolean; // для десятичных чисел со знаком.
  function geStrToUInt(const Str: String; out Value: maxUIntVal; Size: LongWord = isLongWord): Boolean; // для десятичных чисел без знака.
  function geHOBStrToUInt(const Str: String; out Value: maxUIntVal; Size: LongWord = isQWord): Boolean; // для работы с шестнадцатеричными, восьмеричными и двоичными значениями.


Модуль редактирован для разных архитектур. Проверялось только на 64-х битной системе, на 32-х битной не должно вызвать проблем. Для 16-ти и 8-ми битных надо проверять.
В модуле можно поднять уровень текущей архитектуры (UP_CPU в начале модуля). Но вы должны знать, что компилятор это позволяет и система под которую вы это делает (в основном от компилятора зависит). Для 64-х битной системы поднять уровень нельзя на данный момент. При сильном желании (если так хотите) можно, объявите свои данные и работайте с ними. Процедуры вообще не должны зависеть от разрядности системы, поэтому можно поднимать хоть до бесконечности. :)

Добавлен файл конфигурации.

Все функции работают быстрее стандартных (в 2-3 раза), использующих функцию Val. :oops:

Модуль идёт под свободной лицензией Zlib.

Проблему с переполнением вроде решил, требуется проверка.

P. S. хоть какую-то мелочь доделал... правда опять не до конца, надо будет ещё и шестнадцатеричные значения обрабатывать и восьмеричные и двоичные... но тут совсем малость останется. :roll:
P.P.S. хоть шестнадцатеричные, восьмеричные и двоичные числа сейчас можно обработать, но по сути ещё не всё доделано. Осталось ещё числа с плавающей запятой обработать... :idea: :mrgreen:
Последний раз редактировалось Seenkao 23.01.2022 02:54:55, всего редактировалось 6 раз(а).
Seenkao
постоялец
 
Сообщения: 336
Зарегистрирован: 01.04.2020 03:37:12

Re: StrToInt на чистом паскале.

Сообщение zub » 10.01.2022 18:40:41

приложи хоть какойнить тест производительности чтоли
zub
долгожитель
 
Сообщения: 2763
Зарегистрирован: 14.11.2005 23:51:26

Re: StrToInt на чистом паскале.

Сообщение Seenkao » 10.01.2022 20:02:46

всё внутри. Там и тест и как использовать.
у меня примерно так на 100000 итераций :
стандартный StrToInt: 7.7 (7.9)мс
обновлённый StrToInt: 5.0 (5.2)мс
Seenkao
постоялец
 
Сообщения: 336
Зарегистрирован: 01.04.2020 03:37:12

Re: StrToInt на чистом паскале.

Сообщение zub » 10.01.2022 21:24:56

т.е. ты предлагаешь брать результат из глобальной переменной? это же неюзабельно имхо.
кроме того, на скорость гораздо больше влияет работа с строками чем сам IntToStr, вариант умеющий работать подстрокой в строке будет гораздо эффективнее
zub
долгожитель
 
Сообщения: 2763
Зарегистрирован: 14.11.2005 23:51:26

Re: StrToInt на чистом паскале.

Сообщение Seenkao » 10.01.2022 22:14:45

глобальную переменную можно заменить на локальную, для определённого модуля и запрашивать значение оттуда (вообще не понимаю этого, но для библиотек других методов не существует). Можно объявить свою переменную и записывать значения туда, хоть по ссылке. Это уже кто как захочет.

StrToInt хотел написать? ))) Было бы хорошо переписать IntToStr, но в данном случае я упираюсь в проверки строк в FPC. И скорости я не добьюсь. Возможность ускориться будет только в том случае, когда уйдём от строки используемой в FPC, а значит и уйдём от всех необязательных проверок, которые навязаны компилятором (это для меня не обязательные, но люди пользуются не так как я, значит проверки нужны).
Это тот вариант подстроки? Когда со строкой работать как с обычными данными? А как вернуть это обратно в строку, чтоб FPC рассматривал это как строку?

По сути можно сделать свою систему работы со строкой (вероятнее всего уже есть), где работа идёт с данными напрямую, но об многом используемом в FPC/Lazarus можно тогда будет забыть. Потому что для них нужно будет вернуть именно их строку, а не подмену, а это означает что мы всё равно потеряем в переводе строки в строку (данных в строку).
Seenkao
постоялец
 
Сообщения: 336
Зарегистрирован: 01.04.2020 03:37:12

Re: StrToInt на чистом паскале.

Сообщение zub » 10.01.2022 22:35:09

да, StrToInt конечно
я имею ввиду чтото типа
geStrToInt(const Str: String; Start,Len:Integer; Size: LongWord = isInteger)
при парсинге основное время какраз уходит на выдирание подстрок из строк, можно хорошо сэкономить передавая не подстроки а их адрес в большой строке.

ну и кроме того, конечно нужно отказаться от гото и заюзать генерики))
zub
долгожитель
 
Сообщения: 2763
Зарегистрирован: 14.11.2005 23:51:26

Re: StrToInt на чистом паскале.

Сообщение Seenkao » 10.01.2022 22:53:06

точно ведь, я забываю о некоторых вещах... Ну значит можно ещё ускорить код. )))

zub писал(а):ну и кроме того, конечно нужно отказаться от гото и заюзать генерики))

когда-нибудь гляну и посмотрю конечный код. Если выползет по коду фигня какая-нибудь, точно пользоваться не буду. :)

Добавлено спустя 2 минуты 48 секунд:
zub писал(а):const Str: String;

офигеть... "про слона-то я и забыл..." :mrgreen: :mrgreen: :mrgreen:
ещё ускорение в полтора раза.

Премногоблагодарствую! :D
Seenkao
постоялец
 
Сообщения: 336
Зарегистрирован: 01.04.2020 03:37:12

Re: StrToInt на чистом паскале.

Сообщение скалогрыз » 11.01.2022 21:07:16

погоди, ты парсер сравниваешь с конвертатором? как-то не шибко честный тест?!

стандартная узнаёт "+"
Код: Выделить всё
writeln(strToIntDef('+1',0));


Seenkao писал(а):Функция не вылетит с ошибкой!

выше уже написал. Используй StrToIntDef или TryStrToInt
(StrToInt с exception-ом это веенье тогдашней моды... ну как сейчас шаблонами обмазываться)

PS: если Val() и тормозит, то похоже из-за того, что пытается перевести AnsiString в ShortString... как бы лишнее копирование.
скалогрыз
долгожитель
 
Сообщения: 1797
Зарегистрирован: 03.09.2008 02:36:48

Re: StrToInt на чистом паскале.

Сообщение Seenkao » 11.01.2022 23:02:57

скалогрыз писал(а):ты парсер сравниваешь с конвертатором?

разве я виноват в том, что вместо обычного перевода, они решили конвертировать данные?

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

скалогрыз писал(а):Используй StrToIntDef или TryStrToInt


а скорость? С помощью zub-а я увеличил скорость в два с лишним раза (а я ещё не брался за шестнадцатеричные, восьмеричные и двоичные значения, где можно просто сдвигом всё делать).

скалогрыз писал(а):если Val() и тормозит

fpcVal - как бы обновляют. По быстрому просматривая код, вижу кучу вызовов, с кучей данных... мне уже это не нравится. Но пока не тестировал.
обсуждение на багтрекере. (лучше бы не читал... он будет ещё медленнее).
Последний раз редактировалось Seenkao 11.01.2022 23:11:08, всего редактировалось 1 раз.
Seenkao
постоялец
 
Сообщения: 336
Зарегистрирован: 01.04.2020 03:37:12

Re: StrToInt на чистом паскале.

Сообщение zub » 11.01.2022 23:09:16

>>я увеличил скорость в два с лишним раза
это синтетическое увеличение. производительность жрут перегоны строк туда-сюда
zub
долгожитель
 
Сообщения: 2763
Зарегистрирован: 14.11.2005 23:51:26

Re: StrToInt на чистом паскале.

Сообщение Seenkao » 11.01.2022 23:12:10

при работе с цифрами (а многие как раз работают с цифрами), это даст значительное ускорение.
Понятно дело, что это не ускорит работу со строками в принципе, если их не надо будет переводить. :)
Seenkao
постоялец
 
Сообщения: 336
Зарегистрирован: 01.04.2020 03:37:12

Re: StrToInt на чистом паскале.

Сообщение Alexander » 12.01.2022 12:53:46

А если её доделать до совместимого с FPC вызова и заменить в основной ветке FPC ? Ускорение всегда нужно.
Аватара пользователя
Alexander
энтузиаст
 
Сообщения: 604
Зарегистрирован: 18.12.2005 19:10:00
Откуда: оттуда

Re: StrToInt на чистом паскале.

Сообщение Seenkao » 12.01.2022 13:29:46

Доделать то, доделаю, только боюсь не протолкнуть будет это.
У меня такое ощущение, что там просто упираются против улучшения. Хотя я даже не предлагал на замену, предложил как вариант использования.
Seenkao
постоялец
 
Сообщения: 336
Зарегистрирован: 01.04.2020 03:37:12

Re: StrToInt на чистом паскале.

Сообщение Alexander » 12.01.2022 15:28:14

У меня сложилось такое же ощущение. Но на замену ещё лучше. Можно оформить и как патч, если не захотят включать.

Добавлено спустя 3 часа 29 минут 20 секунд:
Протестировал. У меня он выдаёт:

Код: Выделить всё
first@my:~/mysites/smfg/soft/GORG64/geStrToInt$ ./project1
Wait...

Test begin.
StrToInt standard     1.2764969929610148E+001
StrToInt made by me  7.0074765044863865E+000
Test Speed Single and Integer  6.9267239712252477E+000
Test Speed Single all          9.9219571859529712E+000
Test end.

255027633

Numbers:
1884041200
-1884041200
0
188404120
0
18840412
0
-188404120
0
-18840412
231158691
-231158691
1
23115869
91
2311586
-1
-23115869

QWord
0

Int64
9223372036854775807

Byte
250
Аватара пользователя
Alexander
энтузиаст
 
Сообщения: 604
Зарегистрирован: 18.12.2005 19:10:00
Откуда: оттуда

Re: StrToInt на чистом паскале.

Сообщение скалогрыз » 12.01.2022 21:47:54

Seenkao писал(а):Я ищу конкретный рабочий способ перевода данных, с минимальными затратами, и по возможности безглючный

ты может и ищешь способ перевода данных.
но у тебя его нет. У тебя пока есть только проверка данных.

вот когда твоя функция вмето bool будет возвращать соответствующий int значение, ну тогда - да.
тогда можно будет сравнивать по времени.

а сейчас ты делаешь только половину работы.
скалогрыз
долгожитель
 
Сообщения: 1797
Зарегистрирован: 03.09.2008 02:36:48

След.

Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

Рейтинг@Mail.ru
cron