vic7tar | Дата: Четверг, 18.01.2018, 00:45 | Сообщение # 1 |
Рядовой
Группа: Пользователи
Сообщений: 12
Статус: Offline
| Всем привет. Для тестирования понадобилась длинная строка. Сваял вот такое: Код Function shaping_str(ByRef m_repeat As long, ByRef m_max_literals As Long, ByRef m_max_spases As Long) As String ' m_repeat - число повторов ' m_max_literals - max длина подстроки ' m_max_spases - max длина промежуточных пробелов Dim m_output_str As String Dim As Long i Randomize m_output_str = "" for i=1 to m_repeat m_output_str = m_output_str + string(int(1 + m_max_literals*Rnd()),"o") + space(int(1 + m_max_spases*Rnd())) Next Return m_output_str+"|" End Function . . . src = shaping_str(1000000,20,10) Ну уж очень долго получается. Подскажите, как кардинально это можно поменять. Заранее спасибо.
|
|
| |
Alecsis | Дата: Понедельник, 29.01.2018, 00:29 | Сообщение # 2 |
Рядовой
Группа: Пользователи
Сообщений: 6
Статус: Offline
| Привет! Если в цикле избавиться от наращивания выходной строки через операцию "+", т.е. от конструкции m_output_str = m_output_str + [довесок из символов с пробелами] то скорость увеличится не в разы, а на порядки… --------------------------------------------- PS что-то не догоняю, приложились ли файлы… на всякий случай ссылка на яндекс-диск, там 2 варианта исходников + протоколы запусков: https://yadi.sk/d/1pR1rKlD3Rs5rq
Сообщение отредактировал Alecsis - Понедельник, 29.01.2018, 00:46 |
|
| |
vic7tar | Дата: Среда, 31.01.2018, 15:51 | Сообщение # 3 |
Рядовой
Группа: Пользователи
Сообщений: 12
Статус: Offline
| Alecsis, спасибо. Действительно, работает на порядки быстрее. Для себя урок - если используешь что-то большое - без CAllocate/Deallocate и указателей не обойтись.
|
|
| |
Somerick | Дата: Суббота, 09.02.2019, 09:56 | Сообщение # 4 |
Рядовой
Группа: Пользователи
Сообщений: 14
Статус: Offline
| Да, тип String тормозной, в таком применении особенно. Используйте функции копирования, заполнения памяти, например memset из С-библиотеки (Для ещё большей скорости - разрабатывать узкоспецифичные ассемблерные. Заполнять память можно блоками по несколько байт, Integer-ами и затем остаток байтами)
Код #Include Once "crt.bi"' memset, etc..
Function A_shaping_str(m_repeat As Integer,m_max_literals As Integer,m_max_spases As Integer)As ZString Ptr
'max size (if rnd=1) Dim As zString Ptr m=Allocate((m_repeat*(m_max_literals+m_max_spases+2))+2),p=Any
If m Then p=m Randomize For i As Integer=1 To m_repeat Dim As Integer x=int(1 + m_max_literals*Rnd) p=memset(p,Asc("o"),x)+x x=int(1 + m_max_spases*Rnd) p=memset(p,Asc(" "),x)+x Next
Poke Short,p,Asc("|")'final char and null Return m Else 'Show "Function A_shaping_str: Memory Allocation Error!" Message ? EndIf End Function
Dim As ZString Ptr m=A_shaping_str(3,10,4) If m Then'Check <>0
?*m
'....
DeAllocate m EndIf Sleep
И непонятно, зачем у вас все параметры как указатели (ByRef ). Когда ничего из функции по ним не передаётся, в данном случае ByRef для Long излишен. Крохотная, совсем маленькая незначительная но тоже потеря производительности. Можно вовсе не указывать, будет как ByVal.
Рандомгенерацию тоже можно рассмотреть на предмет оптимизаций. Может быть в каких-то случаях не нужно высокое, криптографическое качество, а сойдёт генератор попроще но гораздо быстрее. RND, вроде бы, double. Заменив операции с плавающей точкой на целочисленные, возможно ещё немножко выжать.
Это не самый простой, можно сделать ещё проще и быстрее. zRndi - базовый генератор 0 ... 99999 zRndMax(rmax) и zRndMinMax(rmin, rmax) - не ограничены этим диапазоном, а ограничиваются аргументами Рандомизация происходит автоматически, не требуется но можно вызывать zRandomize zRnd - выдаёт double 0 ... 1 как Rnd
асм 32 бита. Код Extern "Windows" Dim Shared As Long zRndData
Function zRndi naked As Long Asm:mov eax, [zRndData]cmp eax,20 jg Short zR1 rdtsc zR1: xor edx,edx mov ecx,127773 div ecx mov ecx,eax mov eax,16807 mul edx mov edx,ecx mov ecx,eax mov eax,2836 mul edx sub ecx,eax xor edx,edx mov eax,ecx mov [zRndData],ecx mov ecx,100000 div ecx mov eax,edx ret End Asm End Function
Function zRndMax naked(rmax As ULong)As ULong Asm:Call _zRndi@0 mov ecx,[esp+4] Xor edx,edx test ecx,ecx jz zRndMax_e0 cmp ecx,99999 ja zRndMax_1 inc ecx div ecx zRndMax_e0: mov eax,edx ret 4
zRndMax_1: imul eax,42950'4294967295/99999 Add al, [zRndData]inc ecx test ecx,ecx jz zRndMax_2 div ecx mov eax,edx zRndMax_2: ret 4 End Asm End Function
Function zRndMinMax naked(rmin As ULong,rmax As ULong)As ULong Asm:mov ecx,[esp+8] sub ecx,[esp+4] push ecx call _zRndMax@4 add eax,[esp+4] ret 8 End Asm End Function
Function zRnd naked()As Double Static As Const Double d=0.000010000100001 Asm:call _zRndi@0 push eax fild dword ptr [esp]add esp,4 fmul qword Ptr [d]ret End Asm End Function
Sub zRandomize Asm:rdtsc movzx ecx,ax mov [zRndData],ecx ret End Asm End Sub End Extern
Получается так:
Код #Include Once "crt.bi"' memset, etc..
Function A_shaping_str(m_repeat As Integer,m_max_literals As ULong,m_max_spases As ULong)As ZString Ptr
'max size Dim As zString Ptr m=Allocate((m_repeat*(m_max_literals+m_max_spases))+2),p=Any
If m Then p=m For i As Integer=1 To m_repeat Dim As ULong x=zRndMinMax(1,m_max_literals) p=memset(p,Asc("o"),x)+x x=zRndMinMax(1,m_max_spases) p=memset(p,Asc(" "),x)+x Next
Poke Short,p,Asc("|")'final char and null Return m Else 'Show "Function A_shaping_str: Memory Allocation Error!" Message ? EndIf End Function
Dim As ZString Ptr m=A_shaping_str(3,10,4) If m Then'Check <>0
?*m
'....
DeAllocate m EndIf Sleep
Сообщение отредактировал Somerick - Суббота, 09.02.2019, 10:35 |
|
| |