powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Быстрая замена символа
25 сообщений из 259, страница 1 из 11
Быстрая замена символа
    #39676186
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Может, кто подскажет, как ещё быстрее можно...

Начал с такого
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
function FastCommatopoint(s: string): string;
var
  i: Integer;
begin
  Result := s;
  for i := 1 to Length(s) do
    if Result[i] = ',' then
      Result[i] := '.';
end;



Сейчас дошёл до такого
Код: 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.
function UseRepneScasb(s: string): string;
const
  COMMA_ = ',';
  DOT_ = '.';
begin
  Result := s;

  asm
    Push  ESI
    Push  EBX

    Mov   EAX,Result

    Mov EDI, [EAX]
    Mov   ECX,[EDI-4]
    Sub ECX, 1

    Mov   AL,COMMA_
    Mov   BL,DOT_

    Cld
@Next:
    repne scasb
    jecxz @Exit
    Mov   [EDI-1],BL
    Jmp   @Next

@Exit:
    Pop  EBX
    Pop  ESI

  end;
end;



Разница
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39676191
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 секунды - это такие длинные строки или в цикле?
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39676196
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
wadman2 секунды - это такие длинные строки или в цикле?

Строки - 250 Char
ии 10 млн раз ...
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39676197
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zinpubwadman2 секунды - это такие длинные строки или в цикле?

Строки - 250 Char
ии 10 млн раз ...
Лучшеб код сравнения, чем словесное описание. Тут все, конечно, джентльмены, но... :)
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39676203
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А так?
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
procedure FastCommatopoint(var s: string);
var
  i: Integer;
begin
  for i := 1 to Length(s) do
    if s[i] = ',' then
      s[i] := '.';
end;
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39676204
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
wadman,
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39676211
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zinpub,

DevEx специально используете?
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39676212
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
procedure ReplaceChar(const Source, Target: Char; var Str: string);
var
  P: PChar;
  I:Integer;
begin
  Result := Str;
  P := Pointer(Result);
  for i := 0 to Length(Str) - 1 do
  begin
    if P^ = Source then
      P^ := Target;
    Inc(P);
  end;
end;


Сильно отличается от asm варианта?
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39676213
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_А так?
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
procedure FastCommatopoint(var s: string);
var
  i: Integer;
begin
  for i := 1 to Length(s) do
    if s[i] = ',' then
      s[i] := '.';
end;



Так хорошо, но копирование снаружи тогда возникает...
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39676215
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 2
Код: pascal
1.
2.
3.
4.
5.
6.
procedure ReplaceChar(const Source, Target: Char; var Str: string);
var
  P: PChar;
  I:Integer;
begin
  Result := Str;
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39676221
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Василий 2
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
procedure ReplaceChar(const Source, Target: Char; var Str: string);
var
  P: PChar;
  I:Integer;
begin
  Result := Str;
  P := Pointer(Result);
  for i := 0 to Length(Str) - 1 do
  begin
    if P^ = Source then
      P^ := Target;
    Inc(P);
  end;
end;


Сильно отличается от asm варианта?

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

авторrepne scasb

у тебя там ansi строки?
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39676230
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
makhaon,
Ага, delphi5
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39676234
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_zinpub,

DevEx специально используете?

А что с ним не так?
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39676236
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
zinpub_Vasilisk_zinpub,

DevEx специально используете?

А что с ним не так?

Понял, пардон, кидал на форму, что под рукой было.
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39676374
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 2
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
procedure ReplaceChar(const Source, Target: Char; var Str: string);
var
  P: PChar;
  I:Integer;
begin
  Result := Str;
  P := Pointer(Result);
  for i := 0 to Length(Str) - 1 do
  begin
    if P^ = Source then
      P^ := Target;
    Inc(P);
  end;
end;


Сильно отличается от asm варианта?

Фи
Код: pascal
1.
2.
3.
4.
5.
6.
 while P^ <> nil do 
  begin
    if P^ = Source then
        P^ := Target;
     Inc(P);
  end;
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39676380
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гирлионайльдо
Код: pascal
1.
 while P^ <> nil do 


А если никогда не будет?
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39676384
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanА если никогда не будет?Видимо имелось ввиду:
Код: pascal
1.
while P^ <> #0 do 

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

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
function ReplaceCharByPChar(const s: string): string;
const
  COMMA_ = ',';
  DOT_ = '.';
var
  P: PChar;
  I: Integer;
begin
  Result := s;
  P := Pointer(Result);
  for i := 0 to Length(s) - 1 do
  begin
    if P^ = COMMA_ then
      P^ := DOT_;
    Inc(P);
  end;
end;



Использование while - ускорения не даёт, и чуть замедляет...
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39676396
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zinpubИспользование while - ускорения не даёт, и чуть замедляет
ну понятно. нативный loop и должен быть быстрее велосипедного, иначе зачем он нужен.
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39676409
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да. Там #0 (Прироста нету... Странно ведь!)


Сделал тест на токио. С включённой оптимизацией

Результаты
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
------------------------------------------------------
ForkReplaceC_lodsw   -> 00:00:211
ReplaceCharByPChar   -> 00:00:208
TestMy               -> 00:00:207
------------------------------------------------------
ForkReplaceC_lodsw   -> 00:00:212
ReplaceCharByPChar   -> 00:00:207
TestMy               -> 00:00:208
------------------------------------------------------
ForkReplaceC_lodsw   -> 00:00:220
ReplaceCharByPChar   -> 00:00:213
TestMy               -> 00:00:218
------------------------------------------------------
ForkReplaceC_lodsw   -> 00:00:211
ReplaceCharByPChar   -> 00:00:210
TestMy               -> 00:00:208
------------------------------------------------------
ForkReplaceC_lodsw   -> 00:00:212
ReplaceCharByPChar   -> 00:00:212
TestMy               -> 00:00:212




Код
Код: 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.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TCommatFunc = function(s: string): string;

  TForm1 = class(TForm)
    btnCommaToPoint: TButton;
    mmo1: TMemo;
    mmo2: TMemo;
    btnFill: TButton;
    procedure btnCommaToPointClick(Sender: TObject);
    procedure btnFillClick(Sender: TObject);
  private
    function RunFunc(Func: TCommatFunc): TDateTime;

    procedure FillRandomText(const iFactor, iCharCount: Integer);
    { Private declarations }
  public
    { Public declarations }
  end;

const
  CNT_RUN = 1000000;

var
  Form1: TForm1;

implementation

{$R *.DFM}

function ForkReplaceC_lodsw(s: string): string;
const
  COMMA_ = ',';
  DOT_ = '.';
begin
  Result := s;

  asm
    Push  ESI
    Push  EBX

    Mov   EAX,Result
    Or    EAX,EAX
    Jz    @Exit
    Mov   ESI,[EAX]
    Or    ESI,ESI
    Jz    @Exit

    Mov   BH,COMMA_
    Mov   BL,DOT_
    Cmp   AH,BL
    Jz    @Exit

    Mov   ECX,[ESI-4]
    Jecxz @Exit
    push ECX

    shr ECX,1

    Cld
  @Next:
    Lodsw
    Cmp   AH,BH
    Jne   @Skip1
    Mov   [ESI-1],BL
  @Skip1:
    Cmp   AL,BH
    Jne   @Skip
    Mov   [ESI-2],BL
  @Skip:
    Dec   ECX
    Jnz   @Next

    // ------------------------
    pop ECX
    and ECX,2
    jz @Exit
  @Next20:
    Lodsb
    Cmp   AH,BH
    Jne   @Skip20
    Mov   [ESI-1],BL
  @Skip20:
    Dec   ECX
    Jnz   @Next20
  @Exit:
    Pop  EBX
    Pop  ESI

  end;
end;

function ReplaceCharByPChar(const s: string): string;
const
  COMMA_ = ',';
  DOT_ = '.';
var
  P: PChar;
  i: Integer;
begin
  Result := s;
  P := Pointer(Result);
  for i := 0 to Length(s) - 1 do
  begin
    if P^ = COMMA_ then
      P^ := DOT_;
    Inc(P);
  end;
end;

function TestMy(const s: string): string;
const
  COMMA_ = ',';
  DOT_ = '.';
var
  P: PChar;
begin
  Result := s;
  P := Pointer(Result);
  while P^ <> #0 do
  begin
    if P^ = COMMA_ then
      P^ := DOT_;
    Inc(P);
  end;
end;

procedure TForm1.btnCommaToPointClick(Sender: TObject);

  function FormatOutput(const aFuncName: string;
    const iRunTime: TDateTime): string;
  begin
    Result := Format('%-20s -> %s', [aFuncName, FormatDateTime('NN:SS:ZZZ',
      iRunTime)]);
  end;

begin
  mmo1.Lines.Add('------------------------------------------------------');

  mmo1.Lines.Add(FormatOutput('ForkReplaceC_lodsw',
    RunFunc(@ForkReplaceC_lodsw)));

  mmo1.Lines.Add(FormatOutput('ReplaceCharByPChar',
    RunFunc(@ReplaceCharByPChar)));

  mmo1.Lines.Add(FormatOutput('TestMy', RunFunc(@TestMy)));

end;

function TForm1.RunFunc(Func: TCommatFunc): TDateTime;
var
  aStartTime: TDateTime;
  i: Integer;
  s: string;
begin
  s := mmo2.Text;

  aStartTime := Now;

  for i := 0 to 50000 - 1 do
    Func(s);

  Result := Now - aStartTime;
end;

procedure TForm1.FillRandomText(const iFactor, iCharCount: Integer);
var
  i: Integer;
  s: string;
begin
  s := '';

  for i := 0 to iCharCount do
  begin
    if Random(10) > iFactor then
      s := s + ','
    else
      s := s + Chr(40 + Trunc(Random(150)));
  end;

  mmo2.Text := s;

end;

procedure TForm1.btnFillClick(Sender: TObject);
begin
  FillRandomText(10, 5000);
end;

end.

...
Рейтинг: 0 / 0
Быстрая замена символа
    #39676411
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вносил правки. И изменил на

Код: pascal
1.
2.
 for i := 0 to 50000 - 1 do
    Func(s);



а так же
Код: pascal
1.
  FillRandomText(10, 5000);
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39676414
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ГирлионайльдоВносил правки. И изменил на

Код: pascal
1.
2.
 for i := 0 to 50000 - 1 do
    Func(s);



а так же
Код: pascal
1.
  FillRandomText(10, 5000);



Factor =10, в FillRandom... Не проставит запятые
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39676415
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Василий 2
Код: pascal
1.
2.
3.
4.
5.
6.
procedure ReplaceChar(const Source, Target: Char; var Str: string);
var
  P: PChar;
  I:Integer;
begin
  Result := Str;


Переделывал из кода, где возвращается копия с замененными символами, остался артефакт
...
Рейтинг: 0 / 0
Быстрая замена символа
    #39676423
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Василий 2_Vasilisk_пропущено...

Переделывал из кода, где возвращается копия с замененными символами, остался артефакт

Я её допеределывал, чуууть медленнее асма
...
Рейтинг: 0 / 0
25 сообщений из 259, страница 1 из 11
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Быстрая замена символа
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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