FreeBasic
Главная
Вход
Регистрация
Четверг, 20.06.2019, 14:18Приветствую Вас Гость | RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Форум » Freebasic » Вопросы по языку FreeBasic » Как сформировать длинную строку?
Как сформировать длинную строку?
vic7tarДата: Четверг, 18.01.2018, 00:45 | Сообщение # 1
Рядовой
Группа: Пользователи
Сообщений: 11
Репутация: 0
Статус: 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
Рядовой
Группа: Пользователи
Сообщений: 1
Репутация: 0
Статус: Offline
Привет!
Если в цикле избавиться от наращивания выходной строки через операцию "+", т.е. от конструкции
m_output_str = m_output_str + [довесок из символов с пробелами]
то скорость увеличится не в разы, а на порядки…
---------------------------------------------
PS что-то не догоняю, приложились ли файлы… surprised
на всякий случай ссылка на яндекс-диск, там 2 варианта исходников + протоколы запусков:
https://yadi.sk/d/1pR1rKlD3Rs5rq


Сообщение отредактировал Alecsis - Понедельник, 29.01.2018, 00:46
 
vic7tarДата: Среда, 31.01.2018, 15:51 | Сообщение # 3
Рядовой
Группа: Пользователи
Сообщений: 11
Репутация: 0
Статус: Offline
Alecsis, спасибо. Действительно, работает на порядки быстрее. Для себя урок - если используешь что-то большое - без CAllocate/Deallocate и указателей не обойтись.
 
SomerickДата: Суббота, 09.02.2019, 09:56 | Сообщение # 4
Рядовой
Группа: Пользователи
Сообщений: 14
Репутация: 2
Статус: 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
 
Форум » Freebasic » Вопросы по языку FreeBasic » Как сформировать длинную строку?
  • Страница 1 из 1
  • 1
Поиск: