Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.138.199.50] |
|
Страницы: (3) 1 2 [3] все ( Перейти к последнему сообщению ) |
Сообщ.
#31
,
|
|
|
Допускаю. Однако моей целью было - сделать код как можно быстрее (автор темы жаловался на медленную скорость); и я почти убеждён, что мой алгоритм - самый быстрый!
|
Сообщ.
#32
,
|
|
|
А я почти убежден, что код, мягко говоря, гуано. Лень разбираться в обфусцированных идентификаторах, но уже одно вот это (s - исходная строка, s2 - искомая)
while Ord(s[t])<>0 do s2[t] := s[t]; наводит на оч-чень сильные подозрения |
Сообщ.
#33
,
|
|
|
Так это ж происходит исключительно оттого, что нельзя было портить исходную строку, дабы тест провести миллион раз!
А так-то, в итоговой, конечно этого не будет! |
Сообщ.
#34
,
|
|
|
Цитата Доделал всё и замеры уточнил, и вот что получил:Ну что сказать вам, москвичи, на прощанье... procedure SubStrErase( s,sub:string); var t,c,lenSub:integer; begin; lenSub := length(sub); t := 1; while Ord(s[t])<>0 do begin if s[t]=sub[1] then // начало совпадения слова!? begin c := 0; repeat inc(c); until (s[t+c]<>sub[1+c]); // считаем длину совпадения if c=lenSub then begin repeat dec(c); until (c=0); // ставим символ удаления t := t + lenSub; // много совпало - пропустим много end else inc(t); // со следующего будет проверка end else inc(t); // со следующего будет проверка end; // удаляем ненужные символы t := 1; repeat inc(t); until ((Ord(s[t])=0) or (s[t]='*')); // нашли первую '*' if Ord(s[t])<>0 then begin c := t; repeat inc(c); until ((Ord(s[c])=0) or (s[c]<>'*')); if Ord(s[c])<>0 then begin repeat if s[c]<>'*' then begin s[t] := s[c]; Inc(t); end; Inc(c); until (Ord(s[c])=0); s[t] := Chr(0); end; end; end; ... str := 'Мама мыла раму с Тамарой. Рама сияла амальгамой'; s2 := str; t2 := 0; for pos:=0 to 10000 do begin asm rdtsc mov t1, eax end; FileName := StringReplace( str, 'ама', '', [rfReplaceAll]); asm rdtsc sub eax, t1 mov t1, eax end; t2 := t2 + t1; str := s2; end; WriteLn(t2); t2 := 0; for pos:=0 to 10000 do begin asm rdtsc mov t1, eax end; SubStrErase( str, 'ама'); asm rdtsc sub eax, t1 mov t1, eax end; t2 := t2 + t1; str := s2; end; WriteLn(t2); |
Сообщ.
#35
,
|
|
|
Цитата Славян @ В результате имеем: 91724617 и 32633585. Вначале я хочу сказать что ты молодец - потратил время, написал код, с нами поделился. Немного критики: У меня твой код работает так(5 запусков): 13.044.908 - 16.936.000 6.636.660 - 8.803.730 8.048.265 - 9.641.485 11.583.250 - 17.566.347 13.467.860 - 17.146.036 Как видно разница минимальна 1 И не забывай что у тебя код не универсален, не может быть применим для любого теста - давай до свидания 2 Напиши на каком железе ты запускал и под какой delphi? Мне так кажется что сам компилятор оптимизирует код. Я под берлином запускал на 2 ядерном пне, как у тебя получилось в 3-6 раз медленнее? |
Сообщ.
#36
,
|
|
|
Славян
и кстати да, твой код всегда проигрывает стринг реплейсу. Вот мой вариант: procedure NewErase3(SIn,SSub:String); Var I,I2, BadChar,LenSSub,LenSIn:Integer; begin LenSSub:=Length(Ssub); I:=0; BadChar:=0; LenSIn:=Length(SIn); Repeat inc(I); Begin if SIn[I]=SSub[1] then Begin for I2 := 2 to LenSSub do if SIn[I+I2-1]=SSub[I2] then Begin if I2=LenSSub then Begin Inc(I,LenSSub-1); Inc(BadChar,LenSSub); End; End Else Begin SIn[I-BadChar]:=SIn[I];Break End; End Else SIn[I-BadChar]:=SIn[I]; End; Until I>= LenSIn; SetLength(SIn,LenSIn-BadChar); end; Он быстрее твоего, и без кастылей, но медленее чем стринг реплейса Через тиккаунт, в среднем 187:StringReplace 234:SubStrErase 203:NewErase Но все равно стрингреплейс быстрее почему-то |
Сообщ.
#37
,
|
|
|
Цитата ^D^ima @ Но все равно стрингреплейс быстрее почему-то Потому что Цитата ^D^ima @ Я под берлином В 10+ функцию серьезно допилили. |
Сообщ.
#38
,
|
|
|
Fr0sT
Просто у меня и так все в 1 проход делается, а там за счет чего скорость? |
Сообщ.
#39
,
|
|
|
У строки должны быть функции right(a) и left(a), которые оставляют правые a знаков или левые a знаков
В твоей задаче s=s.right(5); s=s.left(12); |