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

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

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

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

Сообщение alexey38 » 09.04.2013 03:56:59

runewalsh писал(а):У них выставлен старший бит и это валидная UTF-8.

Например, "D0 BE" = "Рѕ". Почему ANSI-текст не может иметь пары символов "Рѕ"? В KOI8/CP1251,CP866 ни коем образом не запрещен старший бит, и его установка в единицу ни как Вам не скажет, что тут именно UTF-8, а не CP1251. Вы можете написать эвристический анализ, смотреть на частоту и периодичность появления байта "D0", и т.п. Но это в любом случае не гарантирует точности идентификации, например, если в Вашем файле русские буквы или спец-значки будут встречаться редко.

Добавлено спустя 8 минут 46 секунд:
runewalsh писал(а):Любая последовательная обработка. Вывод или там конвертирование. Если тебе нужно индексировать БОЛЬШИЕ строки, имеет смысл загружать их по частям, а не тратить 3/4 памяти на нули. Не мешай переменные на стеке размером с регистр и кодировки строк, это совершенно разные вещи.
runewalsh писал(а):Можно указатель на первый символ передавать, прикинь. Обычно итерирования достаточно.

1. Вы приведите пример реального паскалевского кода, который реализует Вашу идею итерирования в реальности.
2. Какие есть задачи последовательной обработки текстовых файлов, кроме как их считывание в некую структуру (структуру классов)?
3. Если все используемые строки легко помещаются в оперативную память, то для каких это целей я должен ухищряться, усложнять алгоритм, загружая строки по частям. Не велика ли цена использования UTF-8 в строковых типах, что он ограничивает алгоритмические возможности языка.

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

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

Сообщение SSerge » 09.04.2013 05:07:57

runewalsh писал(а):А информацию о кодировке несёт тип переменной, т. е. все преобразования известны во время компиляции


Бугагашеньки, практик :mrgreen: Ну-ка, что у нас со смещением -12 от указателя на AnsiString, а?
Код: Выделить всё
Type
  PAnsiRec = ^TAnsiRec;
  TAnsiRec = Record
    CodePage    : TSystemCodePage;
    ElementSize : Word;
{$ifdef CPU64}   
    { align fields  }
   Dummy       : DWord;
{$endif CPU64}
    Ref         : SizeInt;
    Len         : SizeInt;
  end;



Кстати, несмотря на то, что длина есть, но сколько смотрел текст функций, работающих с AnsiString (не все, не все), они таки полагаются на Zero byte в конце оной и пересчитывают поле длины после завершения операции.

все преобразования известны во время компиляции


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

Кстати, чтобы далеко не отходить, а вот вам и мина, которая сработает на 64-битном компиляторе у программера, неосмотрительно пользующегося недокументированными форматами данных:

Код: Выделить всё
{$ifdef CPU64}   
    { align fields  }
   Dummy       : DWord;
{$endif CPU64}
SSerge
энтузиаст
 
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

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

Сообщение alexey38 » 09.04.2013 07:16:10

SSerge писал(а):Во время компиляции известны только преобразования строковых констант, заданных в тексте программы. Все остальные преобразования производятся исключительно во время исполнения.

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

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

Сообщение debi12345 » 09.04.2013 08:37:03

Например, слово "Авто" и примера разобранного несколько страниц назад имеет вид "Авто". Как определить что это такое? Бинарный вид "D0 90 D0 B2 D1 82 D0 BE"?

Разумно было бы (и дело к этому уже идет), ЛЮБОЙ текст ХРАНИТЬ в UTF8. Но использовать UTF8 в виджетах и манипуляциях при том что есть гораздо более быстая и удобная для этих дел кодировка, которая вмещает в себя ВСЕ ЗЕМНЫЕ алфавиты - это только ради интеграции алфавитов инопланетян в HID-ы.

Добавлено спустя 3 минуты 49 секунд:
Идеален UTF32

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

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

Сообщение alexey38 » 09.04.2013 16:01:04

debi12345 писал(а):ЛЮБОЙ текст ХРАНИТЬ в UTF8

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

Добавлено спустя 6 минут 43 секунды:
debi12345 писал(а):В общем случае обесценивает самое ценное (прямо и переносно) в компе - кэши проца.

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

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

Сообщение debi12345 » 09.04.2013 17:59:11

Каким образом Вы заставите всех людей в мире на всех имеющихся компах, устройствах и накопителях перекодировать все имеющиеся данные за все предыдущие годы в UTF8 ?

К этому дело потихоньку движется, и в итоге к этому придем :) Но повторюсь - для ХРАНЕНИЯ плэйн-текстовых данных на физических носителях - ибо нет лучшего компросмисса между юникодностью (переносимостью) и компактностью (КПД = удельной стоимостью носителя). Но ясен перец - никак не для отображения, ввода-вывода данных и манипуляций над ними.

Добавлено спустя 10 минут 14 секунд:
Наличие данных в кэше дает на практике небольшое ускорение, выражаемое в процентах или десятках процентов. Замедление многих задач при работе с UTF8 (и UTF16) достигает порядков, то есть десятков раз.

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

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

Сообщение alexey38 » 09.04.2013 18:25:49

debi12345 писал(а):К этому дело потихоньку движется, и в итоге к этому придем

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

Еще одним аргументов в пользу ВОМа является то, что заготовка файла настроек на чистом английском в формате UTF-8 не отличается от ANSI/ASCII файла. Вы хотите поправить настройки, вписав там русский текст, но Вам непонятно, в какой кодировке нужно делать файл, редактор не распознал. Приходится использовать метод тыка, либо искать инфу глубоко в доке.
alexey38
долгожитель
 
Сообщения: 1627
Зарегистрирован: 27.04.2011 19:42:31

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

Сообщение Сквозняк » 09.04.2013 18:33:12

debi12345 писал(а):1) ЮТФ8 для хранения тексовых файлов2) ЮЦС2 для манипуляций над данными и отображения данных, прочитанными из этих файлов

1) И получаются алгоритмы из дурдома. Чтобы прочитанный из файла UTF-8 текст расфасовать по утф8стрингам, нужно произвести конвертацию. В таком случае 8 битная кодировка для хранения книг лучше: весит меньше а конвертировать при считывании и отображении в любом случае надо.

2) Для манипуляций удобнее чтобы символы были одной длины, вписывались в оную без компрессии и сложностей, чтобы был доступ к произвольному байту. То есть строки с UTF32 содержимым типа:
Код: Выделить всё
type
Byte_word4 = shortstring[4];
Utf32_string = array of Byte_word4;


Добавлено спустя 9 минут 19 секунд:
alexey38 писал(а):Я тоже за уникод, как формат хранения данных на диске, и на диске нет смысла хранить нули.

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

Как вариант, использовать стандартный свободный алгоритм сжатия текстовых файлов и зашить его в видуху чтобы она экономично и быстро архивировала текстовые файлы. Видеофайлы видухи разархивировать умеют, значит и с текстовыми файлами можно сделать тоже самое. Только Utf-8 тут будет только мешать и зря греть железо а 32 битная фарма записи получится самой удобной. Туда даже картинки можно будет пихать, не будет разницы текстовой это символ или нет, главное чтобы занимал 4 байта.
Сквозняк
энтузиаст
 
Сообщения: 1129
Зарегистрирован: 29.06.2006 22:08:32

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

Сообщение alexey38 » 09.04.2013 19:23:33

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

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

Разумно.
http://www.thg.ru/software/test_arhivatorov_7zip_magicrar_winrar_winzip/index.html
http://code.google.com/p/d7zip/ Эту библиотеку использую уже несколько лет, у меня ей сжата некая база данных в виде файлов, в сжатом виде общий объем около 100 Гб, в развернутом более Тб.
alexey38
долгожитель
 
Сообщения: 1627
Зарегистрирован: 27.04.2011 19:42:31

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

Сообщение runewalsh » 09.04.2013 22:13:52

SSerge писал(а):CodePage : TSystemCodePage;

О'кей, был неправ. Но насчёт реализации можешь не беспокоиться, по крайней мере length() разворачивается в зауряднейшее обращение со смещением.
Сквозняк писал(а):Намного лучше если текст хранить в 32 битах но научить все редакторы и читалки сохранять и читать зип архивы.

Тебе не кажецо, что для изменения такого архива его в общем случае придётся перепаковать, что несравнимо медленнее, чем просто сдвинуть данные?
Алгоритмы сжатия с окном очень плохо параллелятся изкоробки — выполнять их в таком виде на видеокарте бессмысленно. Разбиение архива на мелкие блоки упростит параллельную упаковку и распаковку, но ни разу не изменение, не говоря уже о степени сжатия. Короче, смысла в архивации текста ровно столько же, сколько в архивации любых данных с высокой избыточностью. Ну а "поиск (текста) по сжатым файлам" невозможен, т. к. поток сжатых данных почти неотличим от шума.

Набросал тут до жути синтетический тест, выполняющий операции, примерно аналогичные чтению сырых UTF-32/UCS-2 и аналогичной UTF-8 (причём с UCS-2 это будет соответствовать действительности, а с UTF-32 случай почти худший). Разница в обоих случаях — 2.5 раза, ни о каких порядках речи не идёт.
Код: Выделить всё
{$mode objfpc}
{$optimization level3}
{$define DWORDS}

uses
  Windows;

var
  iqpc: extended;

procedure InitPerfTimer;
var
  qpc: int64;
begin
  QueryPerformanceFrequency(qpc);
  iqpc := 1.0 / qpc;
end;

function PerfTime: extended;
var
  qpc: int64;
begin
  QueryPerformanceCounter(qpc);
  result := qpc * iqpc;
end;

type
  pSym_t = ^sym_t;
  sym_t = {$ifdef DWORDS} dword {$else} word {$endif};

const
  SPACE = 64 * 1024 * 1024;
  MASK = %00111111;
  VariableIncrement: array[0 .. 3] of SizeUint =
    (sizeof(sym_t), sizeof(sym_t) - 1, sizeof(sym_t) + 1, sizeof(sym_t));

var
  syms: array of sym_t;
  i, j, lim: integer;
  time: extended;
  x: sym_t;
  bx: packed array[0 .. sizeof(sym_t) - 1] of byte absolute x;

begin
  InitPerfTimer;
  SetLength(syms, SPACE div sizeof(syms[0]));

  time := PerfTime;
  for i := 0 to High(syms) do
    x := syms[i];
  time := PerfTime - time;
  writeln('Raw symbol access: ', time * 1.0e3:0:2, ' ms');

  time := PerfTime;
  i := 0;
  j := 0;
  lim := (length(syms) - 1) * sizeof(syms[0]);
  while i < lim do
  begin
    x := pSym_t(pointer(syms) + i)^;
    x := bx[0] and MASK + (bx[1] and MASK) shl 6
  {$ifdef DWORDS} + (bx[2] and MASK) shl 12 + (bx[3] and MASK) shl 18 {$endif};
    inc(i, VariableIncrement[j]);
    j := (j + 1) mod length(VariableIncrement);
  end;
  time := PerfTime - time;
  writeln('Bitwise perversion: ', time * 1.0e3:0:2, ' ms');
end.
Аватара пользователя
runewalsh
энтузиаст
 
Сообщения: 579
Зарегистрирован: 27.04.2010 00:15:25

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

Сообщение Сквозняк » 10.04.2013 01:53:03

runewalsh писал(а):Тебе не кажецо, что для изменения такого архива его в общем случае придётся перепаковать, что несравнимо медленнее, чем просто сдвинуть данные?

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

Код: Выделить всё
Ну а "поиск (текста) по сжатым файлам" невозможен, т. к. поток сжатых данных почти неотличим от шума.
А разархивация и так происходит - если искать не набор байтов а символы, да ещё осмысленно, то нужно конвертировать наборы байтов из файлов в Utf-8. А если искать 4 байтные символы по сжатым файлам то загоняем в видуху архивы, на выходе получаем массивы которые без перекодирования загружаем в строки или массивы переменных типа Longword и ищем.
Сквозняк
энтузиаст
 
Сообщения: 1129
Зарегистрирован: 29.06.2006 22:08:32

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

Сообщение alexey38 » 10.04.2013 04:46:06

runewalsh писал(а):Набросал тут до жути синтетический тест, выполняющий операции, примерно аналогичные чтению сырых UTF-32/UCS-2 и аналогичной UTF-8 (причём с UCS-2 это будет соответствовать действительности, а с UTF-32 случай почти худший). Разница в обоих случаях — 2.5 раза, ни о каких порядках речи не идёт.

Если честно, то не понял, что выполняет приведенный код, и соответственно что иллюстрирует приведенный замер быстродействия, тем более, что чтения с диска вообще нет (самая медленная операция).

Добавлено спустя 7 минут 44 секунды:
Сквозняк писал(а):если искать не набор байтов а символы, да ещё осмысленно, то нужно конвертировать наборы байтов из файлов в Utf-8

Поиск общего вида в текстовом уникоде требует, во-первых, учета малых и больших букв (поиск идет чаще без учета регистра), но самое страшное в том, что в некоторых языках у некоторых символов есть несколько равнозначных байтовых представлений. Поэтому работая с уникодом в любой его кодировке без "костылей", операция поиска уже не является операцией поиска побайтового совпадения, как было в старых 8-битных строках, здесь требуется вначале как минимум нормализация, а затем возможно и конвертация регистра. Операция распаковки из архива будет сопоставима повремени со всеми вспомогательными операциями над уникодовским текстом.
alexey38
долгожитель
 
Сообщения: 1627
Зарегистрирован: 27.04.2011 19:42:31

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

Сообщение runewalsh » 10.04.2013 06:53:36

UTF-8 как разновидность сжатия — это что-то новенькое ^^ Разве что "сжатие с размером блока в 1 символ".
Никого не нужно фасовать, если файл уже в нужной кодировке.
И что вы заладили про видухи? Аппаратное декодирование видео здесь вообще ни при чём — оно реализуется отдельным блоком GPU и заточено под конкретные кодеки. Сами же GPU рассчитаны на SIMD-задачи, универсальные алгоритмы сжатия (даже с маленьким окном и мелкими блоками) сюда не вписываются в той степени, чтобы дать выигрыш по сравнению с CPU. Именно поэтому для GPU-специфичного сжатия с потерями характерны постоянные коэффициенты, иначе бы не парились и грузили текстуры в JPEG, декодируя непосредственно во время выборки. Пожалуйста, не думайте о GPGPU как о серебряной пуле.
alexey38 писал(а):тем более, что чтения с диска вообще нет (самая медленная операция).

Ты это серьёзно? Чтение не нужно, т. к. займёт одинаковое время. А замерил я сферическую скорость декодирования в вакууме.
alexey38 писал(а):Поиск общего вида в текстовом уникоде требует, во-первых, учета малых и больших букв

А с 8-битными строками не потребует, да? Никто не мешает параллельно поддерживать нормализованную версию текста.
Равнозначные байтовые представления ОДНОГО символа не допускаются стандартом, и это правильно, а на "немного разные" (кроме, разве что, регистра) все дружно забивают. Скопируй в адресную строку своего любимого браузера цифру 5 и сравни с 5.
Аватара пользователя
runewalsh
энтузиаст
 
Сообщения: 579
Зарегистрирован: 27.04.2010 00:15:25

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

Сообщение alexey38 » 10.04.2013 09:39:48

runewalsh писал(а):Ты это серьёзно? Чтение не нужно, т. к. займёт одинаковое время. А замерил я сферическую скорость декодирования в вакууме.

Вы или кто-то другой говорили, что считывание файла UTF-8 в строковую переменную UTF-32 слишком медленная операция, за счет того, что нужно делать преобразования.
Я не понял смысла Вами приведенного алгоритма со сдвижкой на 6 бит, но главное, что быстродействие операции чтения из файла нужно оценивать целиком. Оптимизировать нужно только то, что в сумме занимает значительную часть. Если общее время считывания некого файла займет 1 сек, то ускорение на 1 мс в некой части алгоритма не имеет смысла.

Добавлено спустя 8 минут 45 секунд:
runewalsh писал(а):А с 8-битными строками не потребует, да? Никто не мешает параллельно поддерживать нормализованную версию текста.
Равнозначные байтовые представления ОДНОГО символа не допускаются стандартом, и это правильно, а на "немного разные" (кроме, разве что, регистра) все дружно забивают. Скопируй в адресную строку своего любимого браузера цифру 5 и сравни с 5.

Речь шла о том, что операции с UTF-32 (UCS-16) не медленне, а быстрее, чем операции с UTF-8. Поэтому поиск в любой строке, в т.ч. в строке UTF-8 требует преобразования, поэтому преобразование файла UTF8 в строковую переменную UTF-32 (UCS-16) будет занимать одинаковое время.

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

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

Добавлено спустя 2 минуты 20 секунд:
runewalsh писал(а):UTF-8 как разновидность сжатия — это что-то новенькое ^^ Разве что "сжатие с размером блока в 1 символ".

Идет речь о том, что если один и тот же текст сохранять на диске в UTF32 и в UTF8, то UTF8 будет занимать меньше места, поэтому UTF8 можно понимать, как способ архивации файла UTF32. Но как способ сжатия не очень эффективный, поэтому проще файлы UTF32 сжимать на лету в некий zip (7z) и т.п., тогда и место мало, и глюков нет (UTF8 без ВОМ не отличим от файлов в 8-битных кодировках).
alexey38
долгожитель
 
Сообщения: 1627
Зарегистрирован: 27.04.2011 19:42:31

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

Сообщение hovadur » 10.04.2013 20:02:57

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

у тебя есть примеры таких программ?
hovadur
постоялец
 
Сообщения: 116
Зарегистрирован: 31.01.2013 15:50:41

Пред.След.

Вернуться в Lazarus

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

Сейчас этот форум просматривают: Yandex [Bot] и гости: 220

Рейтинг@Mail.ru