powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Быстрая замена символа
25 сообщений из 259, страница 6 из 11
Быстрая замена символа
    #39677035
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev AlexeyAleksandr Sharahov,

А строки почему только кратные 4?

Не обязательно кратные. Последний кусок может быть не кратным. Но все равно обработается как 4-байтовый интегер. Если подходить формально, то так делать некорректно по 2 причинам:
1. Выход за границу строки. Но т.к. память выделяется кратно 4, то к AV это не приведет.
2. Терминатор обрабатывается как символ данных и теоретически может быть заменен, если нулевой элемент в таблице замен не равен 0. Но тут уж программист в ответе.

Kazantsev AlexeySetLength для необнулённого Result в реальном коде, скорее всего, будет давать просадку.
А какие тут еще варианты? Setstring или присваивание? Надо бы проверить, конечно.

P.S. Код писал, чтобы сравнить с работой с масками по 4 байта. Получилось примерно одинаково.
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677036
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksandr SharahovА какие тут еще варианты? Setstring или присваивание?
Result := ''; SetLength(Result, ...); Без обнуления на потенциальных реаллоках будет ещё копирование данных происходить.
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677043
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev AlexeyAleksandr SharahovА какие тут еще варианты? Setstring или присваивание?
Result := ''; SetLength(Result, ...); Без обнуления на потенциальных реаллоках будет ещё копирование данных происходить.

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

Можно еще такое проверить
Код: pascal
1.
2.
  if Length(Result)>len then Result:='';
  SetLength(Result, len);
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677047
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksandr Sharahov,

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

Я согласен, что всё это тестировать нужно по месту применения, но даже на малых строках вариант с обнулением выигрывает:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
function getstr(const astr : string): string;
begin
//result := '';
 setlength(result, length(astr));
end;

 for index := 1 to 100000000 do begin
  if odd(index) then
   s := getstr('0123456789')
  else
   s := getstr('01234');
   s1 := s;
  end;
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677069
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev AlexeyЯ согласен, что всё это тестировать нужно по месту применения, но даже на малых строках вариант с обнулением выигрывает:


Сейчас проверил на D7 c FastMM и без него.
Получилось, что SetLength без доп.ухищрений быстрее всего. Наверно сделал что-то не так )
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677070
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksandr Sharahov,

Я на XE2 проверял с дефолтным FastMM. Противоположный результат.
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677077
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
schizinpubпропущено...


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

Или, я чего то не понимаю...

Сотня потоков даст непрерывную нагрузку на процессор (перемалывает файлы - ждет завершения ввода-вывода)

Она и есть под постоянной загрузкой, если очередь растёт - запускаются дополнительные машины.
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677078
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
zinpub,

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

Я на XE2 проверял с дефолтным FastMM. Противоположный результат.

Теперь спать не буду)
Вот ведь вопрос: они там что-то улучшили или что-то сломали?
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677083
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Aleksandr SharahovKazantsev AlexeyAleksandr Sharahov,

Я на XE2 проверял с дефолтным FastMM. Противоположный результат.

Теперь спать не буду)
Вот ведь вопрос: они там что-то улучшили или что-то сломали?

А на ХЕ2 строки не уникодные? Я как-то с д7 на ХЕ10 сразу перепрыгнул.
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677085
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zinpubА на ХЕ2 строки не уникодные? Я как-то с д7 на ХЕ10 сразу перепрыгнул.
Юникодные. Они с 2009 юникодные.
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677130
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey,

Да действительно, в некоторых случаях заметно ускорение на уровне ~10%, поправил.
+ Добавил перегруженную функцию, она чуть быстрее, но работает только с одной парой:
Код: 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.
unit ShaCharReplaceUnit;

interface

uses
  SysUtils;

//Do not include #0 into FromChars!
procedure InitCharReplaceTable(const FromChars, ToChars: AnsiString; pCharReplaceTable: pByteArray);
function ShaCharReplace(const s: AnsiString; pCharReplaceTable: pByteArray): string; overload;
function ShaCharReplace(const s: AnsiString; chFrom, chTo: AnsiChar): string; overload;

implementation

//Do not include #0 into FromChars!
procedure InitCharReplaceTable(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 if FromChars[i]<>#0 then pCharReplaceTable[ord(FromChars[i])]:=ord(ToChars[i]);
  end;

function ShaCharReplace(const s: AnsiString; pCharReplaceTable: pByteArray): string;
var
  len: integer;
  p, q: pInteger;
begin
  len:=Length(s);
  Result:='';
  SetLength(Result, len);
  p:=pointer(s);
  q:=pointer(Result);
  while len>0 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;
  end;

function ShaCharReplace(const s: AnsiString; chFrom, chTo: AnsiChar): string;
var
  ch1, ch2, chf, cht, len: integer;
  p, q: pInteger;
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>0 do begin;
    ch1:=pinteger(p)^;
    ch2:=ch1 xor chf;
    ch2:=(ch2 and $7F7F7F7F + $01010101) and $80808080 and ch2;
    pinteger(q)^:=(ch2 - ch2 shr 7 or ch2) and cht xor ch1;
    inc(p);
    inc(q);
    dec(len,4);
    end;
  end;

end.

...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677132
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Aleksandr SharahovKazantsev Alexey,

Да действительно, в некоторых случаях заметно ускорение на уровне ~10%, поправил.
+ Добавил перегруженную функцию, она чуть быстрее, но работает только с одной парой:
Код: 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.
unit ShaCharReplaceUnit;

interface

uses
  SysUtils;

//Do not include #0 into FromChars!
procedure InitCharReplaceTable(const FromChars, ToChars: AnsiString; pCharReplaceTable: pByteArray);
function ShaCharReplace(const s: AnsiString; pCharReplaceTable: pByteArray): string; overload;
function ShaCharReplace(const s: AnsiString; chFrom, chTo: AnsiChar): string; overload;

implementation

//Do not include #0 into FromChars!
procedure InitCharReplaceTable(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 if FromChars[i]<>#0 then pCharReplaceTable[ord(FromChars[i])]:=ord(ToChars[i]);
  end;

function ShaCharReplace(const s: AnsiString; pCharReplaceTable: pByteArray): string;
var
  len: integer;
  p, q: pInteger;
begin
  len:=Length(s);
  Result:='';
  SetLength(Result, len);
  p:=pointer(s);
  q:=pointer(Result);
  while len>0 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;
  end;

function ShaCharReplace(const s: AnsiString; chFrom, chTo: AnsiChar): string;
var
  ch1, ch2, chf, cht, len: integer;
  p, q: pInteger;
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>0 do begin;
    ch1:=pinteger(p)^;
    ch2:=ch1 xor chf;
    ch2:=(ch2 and $7F7F7F7F + $01010101) and $80808080 and ch2;
    pinteger(q)^:=(ch2 - ch2 shr 7 or ch2) and cht xor ch1;
    inc(p);
    inc(q);
    dec(len,4);
    end;
  end;

end.



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

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

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

Кстати, на моем компе вот такое получилось быстрее, не говоря уж о 21590243
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
function ReplaceCommaToDot(const s: string): string;
var
  i: integer;
  p: pChar;
begin
  Result:=s;
  UniqueString(Result);
  p:=pointer(Result);
  i:=(Length(Result)-1) and -4;
  while i>=0 do begin;
    if p[i]  =',' then p[i]  :='.';
    if p[i+1]=',' then p[i+1]:='.';
    if p[i+2]=',' then p[i+2]:='.';
    if p[i+3]=',' then p[i+3]:='.';
    dec(i,4);
    end;
  end;
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677197
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksandr Sharahov,

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

а остаток ? Крокодильчикам?)

А подумать? Крокодильчики съели мозг?
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677202
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Обновил модуль, теперь можно менять любой символ строки (даже #0) на любой:
Код: 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): string; overload;
function ShaCharReplace(const s: AnsiString; chFrom, chTo: AnsiChar): string; 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 if FromChars[i]<>#0 then pCharReplaceTable[ord(FromChars[i])]:=ord(ToChars[i]);
  end;

function ShaCharReplace(const s: AnsiString; pCharReplaceTable: pByteArray): string;
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): string;
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:=pChar(p)[len];
    if ch=chFrom then ch:=chTo;
    pChar(q)[len]:=ch;
    end;
  end;

end.

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

забыл поправить процедуру инициализации с учетом последнего изменения
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
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;
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677219
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksandr Sharahov,

Не то (Прошлый код) и не тот, один и тот же результат
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677222
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если заменить string на AnsiString то норм. Подправь это расхождение. Ато принимаешь AnsiString а возвращаешь string
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39677223
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
25 сообщений из 259, страница 6 из 11
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Быстрая замена символа
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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