powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Быстрая замена символа
25 сообщений из 259, страница 7 из 11
Быстрая замена символа
    #39677250
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Aleksandr SharahovГирлионайльдоЕсли заменить string на AnsiString то норм. Подправь это расхождение. Ато принимаешь AnsiString а возвращаешь string

Спасибо, поправил. Исправленная версия:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
unit ShaCharReplaceUnit;

interface

uses
  SysUtils;

procedure ShaCharReplaceTableInit(const FromChars, ToChars: AnsiString; pCharReplaceTable: pByteArray);
function ShaCharReplace(const s: AnsiString; pCharReplaceTable: pByteArray): AnsiString; overload;
function ShaCharReplace(const s: AnsiString; chFrom, chTo: AnsiChar): AnsiString; overload;

implementation

procedure ShaCharReplaceTableInit(const FromChars, ToChars: AnsiString; pCharReplaceTable: pByteArray);
var
  i, len: integer;
begin;
  for i:=0 to 255 do pCharReplaceTable[i]:=i;
  i:=Length(FromChars);
  len:=Length(ToChars);
  if len>i then len:=i;
  for i:=1 to len do pCharReplaceTable[ord(FromChars[i])]:=ord(ToChars[i]);
  end;

function ShaCharReplace(const s: AnsiString; pCharReplaceTable: pByteArray): AnsiString;
var
  len: integer;
  p, q: pInteger;
begin
  len:=Length(s);
  Result:='';
  SetLength(Result, len);
  p:=pointer(s);
  q:=pointer(Result);
  while len>3 do begin;
    q^:=pCharReplaceTable[p^ shr 24        ] shl 24
     or pCharReplaceTable[p^ shr 16 and 255] shl 16
     or pCharReplaceTable[p^ shr  8 and 255] shl  8
     or pCharReplaceTable[p^        and 255];
    inc(p);
    inc(q);
    dec(len,4);
    end;
  while len>0 do begin;
    dec(len);
    pByteArray(q)[len]:=pCharReplaceTable[pByteArray(p)[len]];
    end;
  end;

function ShaCharReplace(const s: AnsiString; chFrom, chTo: AnsiChar): AnsiString;
var
  ch1, ch2, chf, cht, len: integer;
  p, q: pInteger;
  ch: AnsiChar;
label
  loop, last;
begin;
  len:=Length(s);
  Result:='';
  SetLength(Result, len);
  p:=pointer(s);
  q:=pointer(Result);
  chf:=ord(chFrom) * $01010101;
  cht:=ord(chTo)   * $01010101 xor chf;
  chf:=chf xor integer($FFFFFFFF);
  while len>3 do begin;
    ch1:=p^;
    ch2:=ch1 xor chf;
    ch2:=(ch2 and $7F7F7F7F + $01010101) and $80808080 and ch2;
    q^:=(ch2 - ch2 shr 7 or ch2) and cht xor ch1;
    inc(p);
    inc(q);
    dec(len,4);
    end;
  while len>0 do begin;
    dec(len);
    ch:=pAnsiChar(p)[len];
    if ch=chFrom then ch:=chTo;
    pAnsiChar(q)[len]:=ch;
    end;
  end;

end.



боги индусского кода ))))
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677253
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
defecator,

на самом деле это очень полезная функция,
через нее можно делать всевозможные перекодировки, upper/lower и т.п.
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677269
schi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksandr Sharahovdefecator,

на самом деле это очень полезная функция,
через нее можно делать всевозможные перекодировки, upper/lower и т.п.

LCMapString(Ex) еще более полезная функция, а главное - она уже написана и оттестирована.
А на все остальное с лихвой хватает StringReplace.

Саша, при всем к тебе уважении, рассчитывать на включение такого кода в более или менее серьезный проект - это слишком радужно
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677271
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
schi,

так это, стреляли...
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677280
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь,

сейчас ради интереса сравнил скорость с AnsiUpperCase, она отличается на порядок,
но это, конечно, фигня, недостойная включения в более-менее серьезный проект )
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677323
schi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksandr SharahovИгорь,

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

А кому она нужна, эта скорость AnsiUpperCase в более или менее серьезном проекте ? Правильно - никому. Потому что в серьезных проектах все уже давно перешли на юникод
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677326
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
schiAleksandr SharahovИгорь,

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

А кому она нужна, эта скорость AnsiUpperCase в более или менее серьезном проекте ? Правильно - никому. Потому что в серьезных проектах все уже давно перешли на юникод

Тебе, конечно, видней.
Ты ведь знаешь все более или менее серьезные проекты и все, что им нужно )
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677333
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
schiА кому она нужна, эта скорость AnsiUpperCase в более или менее серьезном проекте ? Правильно - никому. Потому что в серьезных проектах все уже давно перешли на юникод
Внезапно в юникодных дельфях AnsiUpperCase работает с ... юникодом.
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677543
vavan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
schiПотому что в серьезных проектах все уже давно перешли на юникодсразу вспоминается jep 254. надо бы попросить еще поддержку 7-битных строк
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677554
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
schiА на все остальное с лихвой хватает StringReplace.
В более новых версия ее подрихтовали, но вплоть до ХЕ2 на нее было не взглянуть без слез. Убийца производительности. А уж для замены или удаления символов ее юзать - разве что на очень нетребовательных проектах.
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677572
schi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 2schiА на все остальное с лихвой хватает StringReplace.
В более новых версия ее подрихтовали, но вплоть до ХЕ2 на нее было не взглянуть без слез. Убийца производительности. А уж для замены или удаления символов ее юзать - разве что на очень нетребовательных проектах.

Я, за более чем 35 лет программирования, ни разу не видел, чтобы в информационных системах узким местом в производительности была замена символов. Возможно, мне не повезло
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677772
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще вариант с чтением четверками (замена по месту, строки родные). Начинает обходить простейший for с длины строки 5, прирост становится больше с увеличением длины, но не превышает 50%.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
procedure ReplaceChar(var s: string; FromChar, ToChar: Char);
var
  len, tail: Cardinal;
  pStart, pEndDiv4: pChar;

  procedure Repl(p: PChar; FromChar, ToChar: Char); inline;
  begin
    if p^ = FromChar then p^ := ToChar;
  end;

begin
  pStart := Pointer(s);
  len := Length(s);
  tail := len mod 4;
  pEndDiv4 := pStart + len - tail;
  while pStart < pEndDiv4 do
  begin
    Repl(pStart,   FromChar, ToChar);
    Repl(pStart+1, FromChar, ToChar);
    Repl(pStart+2, FromChar, ToChar);
    Repl(pStart+3, FromChar, ToChar);
    Inc(pStart, 4);
  end;

  if tail > 2 then
    Repl(pStart + 2, FromChar, ToChar);
  if tail > 1 then
    Repl(pStart + 1, FromChar, ToChar);
  if tail > 0 then
    Repl(pStart + 0, FromChar, ToChar);
end;
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39679249
Sapersky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
"Ну куда он, куда он гонится?
Неужель он не знает, что живых коней
Победила стальная конница?"
https://godbolt.org/g/zgmGz8
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39679257
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sapersky,

было бы интересно увидеть завершенную процедуру на Delphi (BASM) и замерить скорость.
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39679259
Sapersky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Aleksandr Sharahov,
Вручную конвертировать под дельфийский ассемблер - дурное занятие, недавно была ветка про линковку сишного кода.
Для 64 бит:
{$LINK 'clang_sse.o'}
procedure ReplaceChr(s : PAnsiChar; Cnt : Integer; FromChar, ToChar : AnsiChar); cdecl; external;
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39679262
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sapersky,

ну ладно, будет время проверю при случае.

Ща проверил свои поделки на СЕ.

Ассемблерный выхлоп из-под СЕ оказался медленнее, чем из-под D7, основной цикл на 16 байт длиннее.
Ускорение по сравнению с RTL уменьшилось с 7-9 раз всего до 3 раз.
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39679307
Sapersky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если надо 32 бита, то могу предложить только в виде dll-ки, 32-битные obj так запросто не линкуются и конверсия в omf почему-то не помогает.
procedure ReplaceChr(s : PAnsiChar; Cnt : Integer; FromChar, ToChar : AnsiChar); cdecl; external 'gcc_sse32.dll';
Aleksandr SharahovАссемблерный выхлоп из-под СЕ оказался медленнее, чем из-под D7Там же FPC в качестве компилятора Паскаля, все претензии ему.
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39679309
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sapersky,

Код: pascal
1.
ReplaceChr(var s: PAnsiChar; 



А во вторых
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39679310
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
SaperskyЕсли надо 32 бита, то могу предложить только в виде dll-ки, 32-битные obj так запросто не линкуются и конверсия в omf почему-то не помогает.
procedure ReplaceChr(s : PAnsiChar; Cnt : Integer; FromChar, ToChar : AnsiChar); cdecl; external 'gcc_sse32.dll';
Aleksandr SharahovАссемблерный выхлоп из-под СЕ оказался медленнее, чем из-под D7Там же FPC в качестве компилятора Паскаля, все претензии ему.

http://www.sql.ru/forum/actualfile.aspx?id=21602858] Приложенный файл (Str_Replace_dll32.zip - 132Kb)
это чудовищно.
замена символа превратилась в монстра
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39679311
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39679312
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
*4.1
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39679315
Sapersky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Гирлионайльдо,

да, SSE4 нужен. И нет, s там просто указатель, без var.

авторзамена символа превратилась в монстра
Это просто для тестирования, так-то можно и компактнее. 2 системных dll-ки - багофича последних версий gcc.
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39679316
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sapersky,

результат в ms под D7 (в цикле 20000 раз массив 1024 строк длиной 9..99):

Код: pascal
1.
2.
3.
4.
1000  ShaCharReplace1            - замена 1 на 1
1000  ShaCharReplace2            - таблица 
2875  ReplaceCommaToDot       - цикл развернут x4 
1968  gccReplaceCommaToDot  - sse
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39679318
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksandr Sharahov,

забыл привести исходник:
Код: pascal
1.
2.
3.
4.
5.
6.
function gccReplaceCommaToDot(const s: AnsiString): AnsiString; //
begin
  Result:=s;
  UniqueString(Result);
  ReplaceChr(pointer(Result), Length(Result), ',', '.');
  end;
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39679322
Sapersky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Aleksandr Sharahov,

По-моему на коротких строках начинает упираться в дельфийскую обвязку, все эти UniqueString и т.д.
Т.е. если делать в цикле так:
ReplaceChr(@s[1], c, ',', '.');
то быстро, а если так:
s1 := s;
ReplaceChr(@s1[1], c, ',', '.');
то медленнее в 10 раз (UniqueString создаёт новую строку, а в первом случае нет).
Возможно это более жизненный сценарий, но получается, что тестируем в основном оптимальность перераспределения памяти.
...
Рейтинг: 0 / 0
25 сообщений из 259, страница 7 из 11
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Быстрая замена символа
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]