:: Visual Foxpro, Foxpro for DOS
Re: Удаление лишних пробелов
spinz

Сообщений: 5263
Дата регистрации: 21.01.2016
Ну да, просто делать проверку на кратность 4 в цикле слишком дорого. Лучше проанализировать этот случай за циклом в постобработке.
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Да после Label4 - IMHO стандартная мулька для таких случаев...


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
lulgu

Сообщений: 1838
Дата регистрации: 30.11.2016
Igor Korolyov
wow1970
Все лишние пробелы удаляю так.
Function TextDropSpace
Lparameters tcText
Return ALLTRIM(chrtran(strtran(strtran(tcText, [ ], [ ] + chr[0]), chr[0] + [ ], []), chr[0], []))
EndFunc

strtran - перераспределение памяти, копирование строки. Два раза.
chrtran без замены 1-на-1 (т.е. с "вырезанием" символов) - перераспределение памяти, копирование строки.
ALLTRIM - перераспределение памяти, копирование строки.
Итого 4 операции по копированию символов туда-сюда, выделению и освобождению памяти.

Любопытные у вас "проходы туда-сюда".
Увы, основное время в этом коде занимает замена символов в первом STRTRAN:


Еще тесты, может кому все-же пригодится:




Исправлено 1 раз(а). Последнее : lulgu, 15.01.18 23:08
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
of63

Сообщений: 25240
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Лулгу, вот, если бы идея (если она есть) (переплевывающая монстров программирования ) была выражена всего одной строкой текста, понятной строкой, а потом расшифровывай там ее... до посинения ). Тогда бы тебя поняли
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
lulgu

Сообщений: 1838
Дата регистрации: 30.11.2016
of63
Лулгу, вот, если бы идея (если она есть) (переплевывающая монстров программирования ) была выражена всего одной строкой текста, понятной строкой, а потом расшифровывай там ее... до посинения ). Тогда бы тебя поняли

Зачем же плеваться.
Если без подсказки даже такие коды у вас вызывают затруднения, то ничем не могу помочь.
Если же кому нужно, тот разберется.
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
spinz

Сообщений: 5263
Дата регистрации: 21.01.2016
лулгу просто монстр

очень сильный, завидую
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
of63

Сообщений: 25240
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
не перезваливай, борец, за свой ... код. И это хорошо! ... он код свой представлял... кстати... я не помню. Как представит, так сразу поймем, какой лулгу классный парень )
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
lulgu

Сообщений: 1838
Дата регистрации: 30.11.2016
Словно две бабульки на скамеечке у подъезда.
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
spinz

Сообщений: 5263
Дата регистрации: 21.01.2016
присоединяйся уже
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
of63

Сообщений: 25240
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Молодой еще... ассеблерный код представит, или алгоритм (типа твоего "4 байта в регистрах просто сравнить"). Хз, что в голове у лулгу, он же не говорит ничего, кроме недовольства.
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
vic7tar

Сообщений: 48
Дата регистрации: 27.02.2017
Предлагаю все-же тестировать на одинаковых строках, например:
shaping_str(1000000,20,10)
shaping_str(10000,20,10)
shaping_str(10,20,10)
Результаты будут интересные.
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
of63

Сообщений: 25240
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Предлагаю все-же тестировать на одинаковых строках, например:
shaping_str(1000000,20,10)
shaping_str(10000,20,10)
shaping_str(10,20,10)

Товарищь, дорогой, где КРАТКИЙ АНОНС эсперимента, и главное, предполагаемого результата эксперимента! (но только: "Предлагаю все-же тестировать" )?
Не будут тестировать, если сразу не поймут, ЧТО тестировать. Тем более "скорости" исполнения. Это материя тонкая, и чтобы ее тестировать, надо ... ну, много мата приложить )
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
vic7tar

Сообщений: 48
Дата регистрации: 27.02.2017
А что тут непонятного?
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
spinz

Сообщений: 5263
Дата регистрации: 21.01.2016
Все же удалось добиться существенного увеличения скорости. Мысль читать строку двордами была изначально верной, только реализацию я излишне усложнил, пытаясь обрабатывать весь дворд в одном цикле. А надо было развернуть цикл и последовательно обрабатывать каждый байт из считанного дворда.

Вот сравнительные результаты обработки 8МБ строки - мой вчерашний код, код Леонида и новый код.

1.Строка по 1 пробелу + 1 не пробелу, старый результат 62 млн тактов, у Леонида 161. Новый результат 41
2.Строка по 2 пробела + 2 не пробела, старый результат 95 млн тактов, у Леонида 44. Новый результат 35
3.Строка по 3 пробела + 3 не пробела, старый результат 64 млн тактов, у Леонида 43. Новый результат 34
4.Строка по 4 пробела + 4 не пробела, старый результат 84 млн тактов, у Леонида 45. Новый результат 32
5.Строка по 16 пробелов + 16 не пробелов, старый результат 62 млн тактов, у Леонида 63. Новый результат 53
6.Строка по 4096 пробела + 4096 не пробела, старый результат 44 млн тактов, у Леонида 39. Новый результат 30
7.Строка из одних пробелов, старый результат 34 млн тактов, у Леонида 26. Новый результат 22
8.Строка из одних не пробелов, старый результат 53 млн тактов, у Леонида 161. Новый результат 41

Ассемблерная функция целиком, выглядит без комментов конечно ужасно, но если немного вдуматься, то все очевидно.
push ebp
mov ebp, esp
push edi
push esi
push eax
push ebx
push ecx
push edx
push ebp
rdtsc
push edx
push eax
mov esi,[ebp+08h]
mov al, 20h
mov edi,[ebp+10h]
mov ecx,[ebp+14h]
mov ecx,[ecx]
mov ebp,esi
add ebp,ecx
xor ecx,ecx
xor edx,edx
xor ah,ah
sub esi,4
_1Label_0:
add esi,4
cmp esi,ebp
ja _Exit
mov edx,[esi]
cmp al,dl
jnz _1Label_1
cmp ah,1
jz _2Label_0
inc ah
jmp _1Label_2
_1Label_1:
xor ah,ah
_1Label_2:
shrd ebx,edx,8
inc ecx
cmp ecx,4
jnz _2Label_0
xor ecx,ecx
mov [edi],ebx
add edi,4
_2Label_0:
shr edx,8
cmp al,dl
jnz _2Label_1
cmp ah,1
jz _3Label_0
inc ah
jmp _2Label_2
_2Label_1:
xor ah,ah
_2Label_2:
shrd ebx,edx,8
inc ecx
cmp ecx,4
jnz _3Label_0
xor ecx,ecx
mov [edi],ebx
add edi,4
_3Label_0:
shr edx,8
cmp al,dl
jnz _3Label_1
cmp ah,1
jz _4Label_0
inc ah
jmp _3Label_2
_3Label_1:
xor ah,ah
_3Label_2:
shrd ebx,edx,8
inc ecx
cmp ecx,4
jnz _4Label_0
xor ecx,ecx
mov [edi],ebx
add edi,4
_4Label_0:
shr edx,8
cmp al,dl
jnz _4Label_1
cmp ah,1
jz _1Label_0
inc ah
jmp _4Label_2
_4Label_1:
xor ah,ah
_4Label_2:
shrd ebx,edx,8
inc ecx
cmp ecx,4
jnz _1Label_0
xor ecx,ecx
mov [edi],ebx
add edi,4
jmp _1Label_0
_Exit:
rdtsc
pop edi
sub eax,edi
pop esi
sbb edx,esi
pop ebp
mov edi,[ebp+0Ch]
mov [edi],eax
mov esi,[ebp+14h]
mov [esi],edx
pop edx
pop ecx
pop ebx
pop eax
pop esi
pop edi
mov esp, ebp
pop ebp
ret 0010h

Фоксовый код целиком
_test =""
FOR i = 1 TO 1024*256
_test = _test + SPACE(16) + REPLICATE("1",16)
ENDFOR
res = reduce(_test , " ")
function Reduce
lparameter m.st, m.ch
if len(m.ch)<1
return m.st
endif
if len(m.ch)>1
m.ch=left(m.ch,1)
endif
if !pemstatus(_screen,"reduce_ptr",5)
Declare Integer GetProcessHeap in Win32API
Declare Integer HeapAlloc in Win32Api Integer, Integer, Integer
Declare RtlMoveMemory in Win32API Integer, String, Integer
local m.hhnd, m.ptr, m.st2
m.st2= ;
chr(0x55)+chr(0x89)+chr(0xE5)+chr(0x57)+chr(0x56)+chr(0x50)+chr(0x53)+chr(0x51)+;
chr(0x52)+chr(0x55)+chr(0x0F)+chr(0x31)+chr(0x52)+chr(0x50)+chr(0x8B)+chr(0x75)+;
chr(0x08)+chr(0xB0)+chr(0x20)+chr(0x8B)+chr(0x7D)+chr(0x10)+chr(0x8B)+chr(0x4D)+;
chr(0x14)+chr(0x8B)+chr(0x09)+chr(0x89)+chr(0xF5)+chr(0x01)+chr(0xCD)+chr(0x31)+;
chr(0xC9)+chr(0x31)+chr(0xD2)+chr(0x30)+chr(0xE4)+chr(0x83)+chr(0xEE)+chr(0x04)+;
chr(0x83)+chr(0xC6)+chr(0x04)+chr(0x39)+chr(0xEE)+chr(0x0F)+chr(0x87)+chr(0x94)+;
chr(0x00)+chr(0x00)+chr(0x00)+chr(0x8B)+chr(0x16)+chr(0x38)+chr(0xD0)+chr(0x75)+;
chr(0x09)+chr(0x80)+chr(0xFC)+chr(0x01)+chr(0x74)+chr(0x17)+chr(0xFE)+chr(0xC4)+;
chr(0xEB)+chr(0x02)+chr(0x30)+chr(0xE4)+chr(0x0F)+chr(0xAC)+chr(0xD3)+chr(0x08)+;
chr(0x41)+chr(0x83)+chr(0xF9)+chr(0x04)+chr(0x75)+chr(0x07)+chr(0x31)+chr(0xC9)+;
chr(0x89)+chr(0x1F)+chr(0x83)+chr(0xC7)+chr(0x04)+chr(0xC1)+chr(0xEA)+chr(0x08)+;
chr(0x38)+chr(0xD0)+chr(0x75)+chr(0x09)+chr(0x80)+chr(0xFC)+chr(0x01)+chr(0x74)+;
chr(0x17)+chr(0xFE)+chr(0xC4)+chr(0xEB)+chr(0x02)+chr(0x30)+chr(0xE4)+chr(0x0F)+;
chr(0xAC)+chr(0xD3)+chr(0x08)+chr(0x41)+chr(0x83)+chr(0xF9)+chr(0x04)+chr(0x75)+;
chr(0x07)+chr(0x31)+chr(0xC9)+chr(0x89)+chr(0x1F)+chr(0x83)+chr(0xC7)+chr(0x04)+;
chr(0xC1)+chr(0xEA)+chr(0x08)+chr(0x38)+chr(0xD0)+chr(0x75)+chr(0x09)+chr(0x80)+;
chr(0xFC)+chr(0x01)+chr(0x74)+chr(0x17)+chr(0xFE)+chr(0xC4)+chr(0xEB)+chr(0x02)+;
chr(0x30)+chr(0xE4)+chr(0x0F)+chr(0xAC)+chr(0xD3)+chr(0x08)+chr(0x41)+chr(0x83)+;
chr(0xF9)+chr(0x04)+chr(0x75)+chr(0x07)+chr(0x31)+chr(0xC9)+chr(0x89)+chr(0x1F)+;
chr(0x83)+chr(0xC7)+chr(0x04)+chr(0xC1)+chr(0xEA)+chr(0x08)+chr(0x38)+chr(0xD0)+;
chr(0x75)+chr(0x09)+chr(0x80)+chr(0xFC)+chr(0x01)+chr(0x74)+chr(0x81)+chr(0xFE)+;
chr(0xC4)+chr(0xEB)+chr(0x02)+chr(0x30)+chr(0xE4)+chr(0x0F)+chr(0xAC)+chr(0xD3)+;
chr(0x08)+chr(0x41)+chr(0x83)+chr(0xF9)+chr(0x04)+chr(0x0F)+chr(0x85)+chr(0x6D)+;
chr(0xFF)+chr(0xFF)+chr(0xFF)+chr(0x31)+chr(0xC9)+chr(0x89)+chr(0x1F)+chr(0x83)+;
chr(0xC7)+chr(0x04)+chr(0xE9)+chr(0x61)+chr(0xFF)+chr(0xFF)+chr(0xFF)+chr(0x0F)+;
chr(0x31)+chr(0x5F)+chr(0x29)+chr(0xF8)+chr(0x5E)+chr(0x19)+chr(0xF2)+chr(0x5D)+;
chr(0x8B)+chr(0x7D)+chr(0x0C)+chr(0x89)+chr(0x07)+chr(0x8B)+chr(0x75)+chr(0x14)+;
chr(0x89)+chr(0x16)+chr(0x5A)+chr(0x59)+chr(0x5B)+chr(0x58)+chr(0x5E)+chr(0x5F)+;
chr(0x89)+chr(0xEC)+chr(0x5D)+chr(0xC2)+chr(0x10)+chr(0x00)
m.hhnd=GetProcessHeap()
m.ptr=HeapAlloc(m.hhnd,0,len(m.st2)+16)
RtlMoveMemory(m.ptr,m.st2,len(m.st2))
_screen.addproperty("reduce_ptr",m.ptr)
endif
local m.st3,m.ln
m.st3=replicate(chr(0),len(m.st)+4)
m.ln=len(m.st)
m.eax = 0
Declare CallWindowProc in Win32API Integer, String, Integer @, String @, Integer @
CallWindowProc(_screen.reduce_ptr, m.st+" ", @m.eax , @m.st3, @m.ln)
? m.eax
? m.ln
return 1

P.S. Причем есть возможности для улучшения этого кода - выравнивать чтение и запись по границам двордов.



Исправлено 2 раз(а). Последнее : spinz, 16.01.18 15:47
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
У меня есть такое подозрение, что фокс сам выровняет исходную строку (и буфер передаваемый для out параметра) по границе двойного слова. Он же блоками память выделяет (в своей куче, которой он сам же и управляет)...


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
spinz

Сообщений: 5263
Дата регистрации: 21.01.2016
Да, я тоже так думаю, но в общем случае эту функу необязательно будут вызывать с выровненными адресами
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
ssa

Сообщений: 13007
Откуда: Москва
Дата регистрации: 23.03.2005
Обнаружился небольшой ошибк.
НЕ удаляется лидирующий пробел, но обрезается последний непробельный символ. То бишь есть сдвиг на байт.


------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
spinz

Сообщений: 5263
Дата регистрации: 21.01.2016
Ага есть такое. Просто обрезание лидирующих пробелов в цикле усложнит логику, что сведет на нет выигрыш в скорости. Поэтому предполагается, что лучше начинать обработку строки с первого непробельного символа.

Достаточно перед циклом добавить строчки и поменять регистры цикле так, что источником был edi, а приемником esi
cld
repe scasb
jz _Exit
dec edi

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

А вот обрезание последнего символа - это косячок из-за некратности длины строки 4, о чем и говорил ИК. Постобработку мне было просто лень делать))
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
ssa

Сообщений: 13007
Откуда: Москва
Дата регистрации: 23.03.2005
spinz
у Леонида первый пробел тоже не обрезается.
Хм, что-то я такого не заметил...

------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
spinz

Сообщений: 5263
Дата регистрации: 21.01.2016
Ну, убедиться же недолго, хотя это и из логики очевидно
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 21 (Гостей: 21)

© 2000-2024 Fox Club 
Яндекс.Метрика