Забавный но досадный глюк

Вопросы программирования и использования среды Lazarus.

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

Re: Забавный но досадный глюк

Сообщение alexey38 » 18.04.2013 16:59:04

debi12345 писал(а):"Весь мир", кроме ЛАЗАРУС энд фпГУЙ - сидит на базовом типе ЮТФ16.

Согласен.
Brainenjii писал(а): Для передачи, например, JSON по сети

Для этих целей UTF8 идеальный вариант, т.к. посимвольно индексировать сетевой поток никто не будет. В таком случае и некоторая компактность, т.к. многие символы имеют номер меньше 128, и без использования сложных алгоритмов сжатия.
alexey38
долгожитель
 
Сообщения: 1627
Зарегистрирован: 27.04.2011 19:42:31

Re: Забавный но досадный глюк

Сообщение alexs » 18.04.2013 17:16:56

alexey38
Если вам достался плохой код, который вам НАДО СОПРОВОЖАТЬ - вы его перепишите в любом случае.
И это не относится к теме UTF8.

А так - я просто не могу представить - ЗАЧЕМ нужны постоянные ПОСИМВОЛЬНЫЕ обращения к строке?
Тут уже неоднократно говорилось - основыне операции со строками:
- Найти длину
- Взять подстроку

Ну а насчёт моей выборки - 20 лет кодинга в различных компаниях и для различных предметных областей. Я тщу себя надеждой - что это уже позволяет мне говорить о статитике кода.
И ещё - по большому счёту весь этот тред - тред не о чём.
Мне лично тоже по началу было дико - как это так - символы занимают разное число байт. Но по факту - это не страшно. Главное глупости не писать в коде.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4064
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Забавный но досадный глюк

Сообщение debi12345 » 18.04.2013 17:47:21

Найти длину

Во-о-о - либо из загловка, либо перебрав всю строку. Есть разница ?

Но по факту - это не страшно. Главное глупости не писать в коде.

Да понятно,что можно оптимизировать все - да еще с нашим русским изворотливым типом мышления.
Было дело, что например перепись а на чистый "С" кастомной версии StrPos() для PostgesSQL привела к повышению скорости в 8(!) раз - но за счет выноса кастомной части сравнения на уровень практически Ассемблера. Вроде бы впечатляет, но - все ведь так не закастомишь :)
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: Забавный но досадный глюк

Сообщение alexey38 » 18.04.2013 17:51:39

Brainenjii писал(а):мне часто надо находить подстроку, но ни разу не потребовался доступ к символу по индексу. Ни разу. За все время работы.

Если в целом смотреть массу кода, которая у меня есть (разных авторов), то довольно часто встречаются различные варианты реализации замеры, одних символов на другие. Самый частый - это замена точки на запятую и обратно (хотя это номера литералов меньше 128). Есть всякие там поиски подстрок с заменами, например, в единицах измерения вводится правильный регистр (например, "кг", "кВ", "км", "кА"), но замена идут условная, смотрится, чтобы эти символы шли после цифры, и если пробелов больше, чем один, то заменяется на один пробел, чтобы не произошла замена "квадрат", на "кВадрат", а "10кв", заменилось на "10 кВ". Учитывая, что есть код написанный еще 15-20 лет назад, то многие операции писались вручную в виде циклов, т.к. тогда в системной библиотеке не было соответствующих функций. Но и сегодня сама системная библиотека для выполнения данных операций организует посимвольный поиск с заменой, так что эти алгоритмы встречаются часто.

Добавлено спустя 2 минуты 6 секунд:
alexs писал(а):Тут уже неоднократно говорилось - основыне операции со строками:

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

Добавлено спустя 6 минут 27 секунд:
alexs писал(а):Главное глупости не писать в коде.

Так многие уже написаны и не нами. Например, есть случаи, когда довольно большой текстовый файл с данными загружается в память, немного парсится, но данные не дублируются в иерархии классов, в полях классов хранят смещения к данным. В таком несколько нетипичном подходе есть даже свою плюсы, например, отсутствует дубляж в данных, нет проблем с тем, кто выделит и кто освободит память. Нет проблем с тем, что данные дописываются, и сам указатель на строку постоянно меняется, т.к. при увеличении длины строки она переносится в другую область памяти. Несколько непривычно, но работоспособно, и очень быстро работает, а учитывая что собственно прикладная логика очень там хорошая, то такую прогу не выкинешь.
alexey38
долгожитель
 
Сообщения: 1627
Зарегистрирован: 27.04.2011 19:42:31

Re: Забавный но досадный глюк

Сообщение debi12345 » 18.04.2013 18:05:44

Самый частый - это замена точки на запятую и обратно (хотя это номера литералов меньше 128). Есть всякие там поиски подстрок с заменами, например, в единицах измерения вводится правильный регистр (например, "кг", "кВ", "км", "кА")

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

Но и сегодня сама системная библиотека для выполнения данных операций организует посимвольный поиск с заменой, так что эти алгоритмы встречаются часто.
Потому что невозможно это сделать быстрее - стоит глянуть хотя бы ассемблерный листинг (есно С-ный, без спрятанных аллокаций во время присвоений,...), там видим оффсеты от базоваго регистра. То, что у нас умудрились "наоптимизирвать" (обогнав предельно оптимизированный машинный код).... чудеса !
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: Забавный но досадный глюк

Сообщение alexey38 » 18.04.2013 18:08:12

alexs писал(а):Если вам достался плохой код, который вам НАДО СОПРОВОЖАТЬ - вы его перепишите в любом случае.

Уже много лет мы успешно занимаемся сопровождением в том числе чужого кода, без его переписывания. Переписать код очень сложно, долго и дорого, особенно учитывая необходимость отладки, тестирования и прочего. Сопровождение с минимальным переписыванием (только там, где надо), всех устраивает. Главное это с одной стороны экономит деньги заказчика, а с другой стороны при правильном подходе делает это бизнес довольно прибыльным. Люди получают хорошие зарплаты. Заказчик доволен. Предприятия работают, выпускают продукцию.

Переписывать то, что и так хорошо работает - это самая большая глупость, которая бывает в программировании. В последнее время мы стали просто увольнять программистов, слишком увлекающихся переписыванием работоспособного кода. Зато есть соседняя контора (из бывших коллег), где наоборот все регулярно переписывают, работают там маньяки, денег у них постоянно не хватает, регулярно бегают занимают, мы им даже старые компы бесплатно отдаем (все таки коллеги, хоть и бывшие). Мы проекты клепаем на потоке, а они зависают на года. Они регулярно хвастаются отдельными достижениями в нюансах, хотя целиком ничего не работает.

Добавлено спустя 2 минуты 29 секунд:
alexey38 писал(а):Самый частый - это замена точки на запятую и обратно (хотя это номера литералов меньше 128).

Забыл добавить, ведь это тоже условная замена, точку на запятую нужно менять только внутри числа, но никак не в конце текстового предложения, т.е. и перед и после точки должна идти цифра.
alexey38
долгожитель
 
Сообщения: 1627
Зарегистрирован: 27.04.2011 19:42:31

Re: Забавный но досадный глюк

Сообщение hovadur » 18.04.2013 18:14:05

Проверьте, пожалуйста, кто-нибудь код, предложенный bormant, в linux. Быстрее ли UTF-8 будет UTF-16.
hovadur
постоялец
 
Сообщения: 116
Зарегистрирован: 31.01.2013 15:50:41

Re: Забавный но досадный глюк

Сообщение debi12345 » 18.04.2013 18:37:36

Тестирование от Грэма (автр фпГУЙ) на нашем тесткэйсе:
Clearly not just Linux. My initial test was under FreeBSD 9.1 (64-bit).

The result below is from Windows 2000 (32-bit) running in a VirtualBox
VM. Still faster than UTF-16 and UTF-32.

----------------------------------------------------
Microsoft Windows 2000 [Version 5.00.2195]
(C) Copyright 1985-2000 Microsoft Corp.

Z:unicode_speed>project1
UTF-8:  0 entries in 000:00:00:00.000512
UTF-8 (fpGUI):  0 entries in 000:00:00:00.000976
UTF-16: 0 entries in 000:00:00:00.001932
UTF-32: 0 entries in 000:00:00:00.001767

----------------------------------------------------


Test project was compiled with compiler options:  -gl -O-
- Показать цитируемый текст -


Раз попахивает парадоксом (типа SSE-оптимизации строковых операций, но избирательной - для ЮТФ8), то вполне вероятно что Мартин составит свой тест - уже приближенный к жизни. Хиты кэш кстати ни при чем - иначе ЮТФ32 проиграла бы ЮТФ16.

Добавлено спустя 11 минут 50 секунд:
Переписывать то, что и так хорошо работает - это самая большая глупость, которая бывает в программировании. В последнее время мы стали просто увольнять программистов, слишком увлекающихся переписыванием работоспособного кода. Зато есть соседняя контора (из бывших коллег), где наоборот все регулярно переписывают, работают там маньяки, денег у них постоянно не хватает, регулярно бегают занимают, мы им даже старые компы бесплатно отдаем (все таки коллеги, хоть и бывшие). Мы проекты клепаем на потоке, а они зависают на года. Они регулярно хвастаются отдельными достижениями в нюансах, хотя целиком ничего не работает.

Хрень какая то :) Чем живут-то ? Ходят на работу пешком, раздетые и голодные как узники Освенцима ?
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: Забавный но досадный глюк

Сообщение Sergei I. Gorelkin » 18.04.2013 18:53:19

debi12345 писал(а):Раз попахивает парадоксом (типа SSE-оптимизации строковых операций, но избирательной - для ЮТФ8), то вполне вероятно что Мартин составит свой тест - уже приближенный к жизни. Хиты кэш кстати ни при чем - иначе ЮТФ32 проиграла бы ЮТФ16.


Кстати говоря, strscan (вызываемая из strpos) очень хорошо оптимизируется с помощью SSE, так что при отсутствии совпадений в строке ее реально обработать за (число байт/16) итераций. Но в RTL это пока не сделано...
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1407
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Забавный но досадный глюк

Сообщение debi12345 » 18.04.2013 19:11:00

Кстати говоря, strscan (вызываемая из strpos) очень хорошо оптимизируется с помощью SSE, так что при отсутствии совпадений в строке ее реально обработать за (число байт/16) итераций. Но в RTL это пока не сделано...

Потому что это ее, в случае статической линковки - очень раздует. Хотя можно сделать как сделали в Линуксе - технология "multiarch", когда код, который можно оптимизировать под проц, выносится в ДЛЛ, и в системе хранятся прекомпилиованные версии зашареных библиотек под разные процы. На каком проце запустишь, это дело подхватывает динамический линковщик - ту оптимизацию и получишь. Флагман здесь еснно либа GLIBC :)
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: Забавный но досадный глюк

Сообщение Sergei I. Gorelkin » 18.04.2013 19:36:03

Зависит от платформы, для x86_64 можно использовать SSE код по умолчанию, т.к. все процессоры, способные выполнять x86_64, умеют и SSE.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1407
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Забавный но досадный глюк

Сообщение alexey38 » 18.04.2013 19:56:50

debi12345 писал(а):Хрень какая то Чем живут-то ? Ходят на работу пешком, раздетые и голодные как узники Освенцима ?

У них зарплата в 3-5 раз ниже, но все таки какая-то есть (не раздетые), т.к. кое какие договора у них есть. Те ребята обладают талантом убеждения, они убеждают заказчика, что нужно все переделать. Некоторые соглашаются. Но когда у них все растягивается, то те ребята вынуждены писать всякие там официальные письма, ища оправдания и косяки самого заказчика. Те ребята не глупые, но чрезмерно гордые и самоуверенные, они каждый раз думают, что переписать с нуля можно очень быстро, например, говорят, что перепишут за 1 неделю, но реально уходит полгода-год.
alexey38
долгожитель
 
Сообщения: 1627
Зарегистрирован: 27.04.2011 19:42:31

Re: Забавный но досадный глюк

Сообщение debi12345 » 18.04.2013 20:32:32

Поиск и сравнение строк строк в линуксе (LIBC) сделан с трюками, грубо говоря - загружают первые байты строки в LONGWORD, и далее в цикле инкрементят индекс строки сразу на длину LONGWORD, и сравнивают целымиу LONGWORD-ми. Еще применются некие эмпирически найденые Magic-числа - для быстрого обнаружения конца строки :)

Добавлено спустя 21 час 13 минут 50 секунд:
Найдено, на чем ЮТФ-8 всех сделала :
Z:\unicode_speed>project1
UTF-8:  0 entries in 000:00:00:00.000512
UTF-8 (fpGUI):  0 entries in 000:00:00:00.000976
UTF-16: 0 entries in 000:00:00:00.001932
UTF-32: 0 entries in 000:00:00:00.001767
----------------------------------------
> We really need an alternative to FPC. ;-)
> =====================
> Or to write own (well optimized) patches to FPC.
>
> PS:
> BTW, the test shows 0 found entries that seems to run an wrong way.

Correct, because the slowness of utf-8 in the testcase is probably caused by
the repeated call of strpos() instead of the indexed character operation.
With 0 found entries there is a single call only.

То есть на неправильном коде (или данных, или локали) самого теста.
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: Забавный но досадный глюк

Сообщение bormant » 21.04.2013 00:06:57

По поводу теста под Linux:
модифицированный код:
Код: Выделить всё
{$H+,R-}
uses
  {$ifdef unix}
  cwstring, unix,
  {$endif}
  {$ifdef windows}
  windows,
  {$endif}
  SysUtils;

const
  TRIES = 100;
  CAPACITY = 1000000;
 
var
  i, j: LongWord;
  {$ifdef windows}
  t1, t2: Int64;
  {$endif}
  {$ifdef unix}
  t1, t2: timeval;
  ut: cLong;
  {$endif}
  ansi: AnsiString;
  utf8: Utf8String;
  utf16: UnicodeString;
  utf32: UCS4String;
  c8: AnsiString;
  c16: UCS2Char;
  c32: UCS4Char;
  p: PChar;
  TestCount: LongWord;
 
begin
  SetLength(ansi, CAPACITY);
  for j := 1 to CAPACITY do
    ansi[j] := Char(32 + Random(256 - 32));
  utf8 := AnsiToUtf8(ansi);
  c8 := #$D0#$AF; // 'Я' in utf8
  c16 := #$042F;
  c32 := $042F;

  { UTF-8 test }
  {$ifdef windows}
  QueryPerformanceCounter(t1);
  {$endif}
  {$ifdef unix}
  fpGetTimeOfDay(@t1, nil);
  {$endif}
  TestCount := 0;
  for i := 1 to TRIES do begin
    p := @utf8[1];
    while true do begin
      p := StrPos(p, @c8[1]);
      if p = nil then break;
      Inc(p); Inc(TestCount);
    end;
  end;
  {$ifdef windows}
  QueryPerformanceCounter(t2);
  WriteLn('UTF-8:  ', TestCount, ' entries in ', t2 - t1, ' ticks.');
  {$endif}
  {$ifdef unix}
  fpGetTimeOfDay(@t2, nil);
  WriteLn('UTF-8:  ', TestCount, ' entries in ',
    t2.tv_sec - t1.tv_sec + (t2.tv_usec - t1.tv_usec) / 1000000.0 :0:6, ' seconds.');
  {$endif}

  { UTF-16 test }
  utf16 := UTF8Decode(UTF8);//**
  {$ifdef windows}
  QueryPerformanceCounter(t1);
  {$endif}
  {$ifdef unix}
  fpGetTimeOfDay(@t1, nil);
  {$endif}
  TestCount := 0;
  for i := 1 to TRIES do begin
    for j := 1 to Length(utf16) do
      if utf16[j] = c16 then Inc(TestCount);
  end;
  {$ifdef windows}
  QueryPerformanceCounter(t2);
  WriteLn('UTF-16: ', TestCount, ' entries in ', t2 - t1, ' ticks.');
  {$endif}
  {$ifdef unix}
  fpGetTimeOfDay(@t2, nil);
  WriteLn('UTF-16: ', TestCount, ' entries in ',
    t2.tv_sec - t1.tv_sec + (t2.tv_usec - t1.tv_usec) / 1000000.0 :0:6, ' seconds.');
  {$endif}

  { UTF-32 test }
  utf32 := UnicodeStringToUCS4String(utf16);//**
  {$ifdef windows}
  QueryPerformanceCounter(t1);
  {$endif}
  {$ifdef unix}
  fpGetTimeOfDay(@t1, nil);
  {$endif}
  TestCount := 0;
  for i := 1 to TRIES do begin
    for j := 0 to Length(utf32) - 1 do
      if utf32[j] = c32 then Inc(TestCount);
  end;
  {$ifdef windows}
  QueryPerformanceCounter(t2);
  WriteLn('UTF-32: ', TestCount, ' entries in ', t2 - t1, ' ticks.');
  {$endif}
  {$ifdef unix}
  fpGetTimeOfDay(@t2, nil);
  WriteLn('UTF-32: ', TestCount, ' entries in ',
    t2.tv_sec - t1.tv_sec + (t2.tv_usec - t1.tv_usec) / 1000000.0 :0:6, ' seconds.');
  {$endif}
end.
Собрано как
Код: Выделить всё
$ fpc -O3 testutf8
Прогон:
Код: Выделить всё
$ LANG=ru_RU.CP1251 ./testutf8
UTF-8:  452700 entries in 1.402442 seconds.
UTF-16: 452700 entries in 0.384839 seconds.
UTF-32: 452700 entries in 0.399826 seconds.
Аватара пользователя
bormant
постоялец
 
Сообщения: 408
Зарегистрирован: 21.03.2012 11:26:01

Re: Забавный но досадный глюк

Сообщение hovadur » 21.04.2013 14:44:16

bormant, а у меня твоя программа выдает:
Код: Выделить всё
UTF-8:  1900 entries in 0.111408 seconds.
UTF-16: 1900 entries in 0.227533 seconds.
UTF-32: 1900 entries in 0.239813 seconds.

У меня такая система:
Intel® Core™ i5-2410M CPU @ 2.30GHz × 4
64-разрядная
hovadur
постоялец
 
Сообщения: 116
Зарегистрирован: 31.01.2013 15:50:41

Пред.След.

Вернуться в Lazarus

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

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

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