Sign in to follow this  
Followers 0
GreenBox

_StringRepeatEx, FAST repat string (please move Example Scripts)

6 posts in this topic

#1 ·  Posted (edited)

This post moved to #744390 Edited by GreenBox

Share this post


Link to post
Share on other sites



wow! Very smart!

I like the logic you use. Admirable :)


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

For me, the difference is not that high:

Environment = 3.3.0.0 under  WIN_XP/Service Pack 3 X86
_StringRepeat >>> 230 ms
_StringRepeatEx >>> 1 ms
Is $vResultA = $vResultB? True

AutoIt:3.3.1.5   (Os:WIN_XP/X86/Service Pack 3   Language:0407 Keyboard:00000407 Cpu:X64)
_StringRepeat >>> 238 ms
_StringRepeatEx >>> 2 ms
Is $vResultA = $vResultB? True

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

For me, the difference is not that high:

Environment = 3.3.0.0 under  WIN_XP/Service Pack 3 X86
_StringRepeat >>> 230 ms
_StringRepeatEx >>> 1 ms
Is $vResultA = $vResultB? True

AutoIt:3.3.1.5   (Os:WIN_XP/X86/Service Pack 3   Language:0407 Keyboard:00000407 Cpu:X64)
_StringRepeat >>> 238 ms
_StringRepeatEx >>> 2 ms
Is $vResultA = $vResultB? True

>"X:\App\Development\AutoIt\Program files\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.exe" /run /prod /ErrorStdOut /in "X:\Data\Projects\Useful\StringRepeatEx.au3" /autoit3dir "X:\App\Development\AutoIt\Program files" /UserParams    
+>19:24:55 Starting AutoIt3Wrapper v.1.10.1.14    Environment(Language:0412  Keyboard:00000412  OS:WIN_2008/  CPU:X86  ANSI)
>Running AU3Check (1.54.14.0)  from:X:\App\Development\AutoIt\Program files
+>19:24:56 AU3Check ended.rc:0
>Running:(3.3.0.0):X:\App\Development\AutoIt\Program files\autoit3.exe "X:\Data\Projects\Useful\StringRepeatEx.au3"    
_StringRepeat >>> 5969 ms
_StringRepeatEx >>> 5 ms
Is $vResultA = $vResultB? True
+>19:25:02 AutoIT3.exe ended.rc:0
+>19:25:04 AutoIt3Wrapper Finished
>Exit code: 0    Time: 8.983

I have a TOO SLOW computer with win7, so i need this function.

CPU : Intel(R) Celeron(R) CPU 2.40GHz
RAM : 768 MB = 256 MB PC3200 DDR SDRAM  (3.0-3-3-8 @ 200 MHz)  (2.5-3-3-7 @ 166 MHz) and 512 MB PC3200 DDR SDRAM  (3.0-3-3-8 @ 200 MHz)  (2.5-3-3-7 @ 166 MHz)
O S : Microsoft Windows 7 Ultimate K

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

wow... thats a pretty big gain! The difference becomes less noticeable with larger strings though.

This is your code in the standard UDF format, with error checking added.

; #FUNCTION# ====================================================================================================================
; Name...........: _StringRepeat
; Description ...: Repeats a string a specified number of times.
; Syntax.........: _StringRepeat($sString, $iRepeatCount)
; Parameters ....: $sString      - String to repeat
;                  $iRepeatCount - Number of times to repeat the string
; Return values .: Success - Returns string with specified number of repeats
;                  Failure - Returns an empty string and sets @error = 1
;                  |@Error  - 0 = No error.
;                  |@Error  - 1 = $iRepeatCount is not a number
;                  |@Error  - 2 = $sString is too short - ""
;                  |@Error  - 3 = $iRepeatCount is less than zero.
; Author ........: Greenbox
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _StringRepeat($sString, $iRepeatCount)
   If Not StringIsInt ($iRepeatCount) Then Return SetError (1, 0, "")
   If StringLen($sString) < 1 Then Return SetError (2, 0, "")
   If $iRepeatCount <= 0 Then Return SetError (3, 0, "")

   Local $nResultLen = StringLen($sString) * $iRepeatCount
   Do
      $sString &= $sString
   Until StringLen($sString) >= $nResultLen
   Return StringLeft($sString, $nResultLen)
EndFunc   ;==>_StringRepeat

Mat

Edited by Mat

Share this post


Link to post
Share on other sites

I thought you might like to see your function put to good use.

;Description: Draws a white bitmap divided into 9 equal areas with 5 areas a different colour

Local $begin1 = TimerInit()
$BMP = _BMPCreateMod(450, 300) ;Creates customize bitmap handle (suitable for BMP.au3 UDF only.)
ConsoleWrite("_BMPCreate = " & TimerDiff($begin1) & @CRLF)

Local $begin = TimerInit()

Local $Header = StringLeft($BMP[3], 110); 110 = "0x" + 54bytes
;Local $sImageData = StringTrimLeft($BMP[3], 110)

Local $ext = _StringRepeatEx("00", Mod($BMP[1], 4)) ;Bitmap width correction.

;white 1/3 of line
Local $sWhiteLineSect = _StringRepeatEx('FFFFFF', Int($BMP[1] / 3))

;Black white green line
Local $Line = _StringRepeatEx('00FF00', Int($BMP[1] / 3)) & $sWhiteLineSect & _StringRepeatEx('000000', $BMP[1] - Int($BMP[1] / 3) * 2) & $ext
$sImageDataMod = _StringRepeatEx($Line, Int($BMP[2] / 3)) ; 1/3 of total number of lines.

; white gray white line
$Line = $sWhiteLineSect & _StringRepeatEx('999999', $BMP[1] - Int($BMP[1] / 3) * 2) & $sWhiteLineSect & $ext
$sImageDataMod &= _StringRepeatEx($Line, Int($BMP[2] / 3)) ; Another 1/3 of lines added to $sImageDataMod.

; blue white red line
$Line = _StringRepeatEx('FF0000', Int($BMP[1] / 3)) & $sWhiteLineSect & _StringRepeatEx('0000FF', $BMP[1] - Int($BMP[1] / 3) * 2) & $ext
$sImageDataMod &= _StringRepeatEx($Line, $BMP[2] - (Int($BMP[2] / 3) * 2)) ; Remainder of lines (about 1/3)

$BMP[3] = $Header & StringStripWS($sImageDataMod, 8)

_BMPWrite($BMP, @ScriptDir & "\MyBMP.bmp");Closes the BMP to a file
ConsoleWrite("BMP Write = " & TimerDiff($begin) & @CRLF)
ConsoleWrite("TOTAL TIME = " & TimerDiff($begin1) & @CRLF)
GUICreate("BMP Example", $BMP[1] + 20, $BMP[2] + 20)
GUICtrlCreatePic(@ScriptDir & "\MyBMP.bmp", 10, 10, $BMP[1], $BMP[2])
GUISetState()

Do
    $msg = GUIGetMsg()
Until $msg = -3;$GUI_EVENT_CLOSE

Func _BMPCreateMod($Width, $Height)
    Local $imageData

    ;***BMP header (54bytes total)***
    Local $Header = "0x424D00000000000000003600000028000000" & _
            _Reverse8(Hex($Width, 8)) & _       ;4bytes, bitmap width
            _Reverse8(Hex($Height, 8)) & _  ;4bytes, bitmap hieght
            "0100180000000000" & _
            _Reverse8(Hex(($Height) * ($Width) * 3 + ($Height * Mod($Width, 4)), 8)) & _    ;4bytes, bitmap data size
            "00000000000000000000000000000000"

    ;Local $sRowData = _StringRepeatEx("FFFFFF", $Width) & _StringRepeatEx("00", Mod($Width, 4))
    $imageData = "" ; _StringRepeatEx(_StringRepeatEx("FFFFFF", $Width) & _StringRepeatEx("00", Mod($Width, 4)), $Height)

    Local $BMPHandle[4] = [Mod($Width, 4), $Width, $Height, $Header & $imageData]
    Return $BMPHandle
EndFunc ;==>_BMPCreateMod

;Copied from BMP.au3 file @ http://www.autoitscript.com/forum/index.php?showtopic=27362&view=findpost&p=193704
Func _Reverse8($inHex)
    Return StringMid($inHex, 7, 2) & StringMid($inHex, 5, 2) & StringMid($inHex, 3, 2) & StringMid($inHex, 1, 2)
EndFunc ;==>_Reverse8

;Copied from BMP.au3 file @ http://www.autoitscript.com/forum/index.php?showtopic=27362&view=findpost&p=193704
Func _BMPWrite(ByRef $BMPHandle, $Fpath, $Progress = 1)
    If IsArray($BMPHandle) = False Then Return 0
    $out = FileOpen($Fpath, 18)
    If $out = -1 Then Return -1
    FileWrite($out, $BMPHandle[3])
    FileClose($out)
    Return 1
EndFunc ;==>_BMPWrite

; http://www.autoitscript.com/forum/index.php?showtopic=105167&view=findpost&p=743550
Func _StringRepeatEx($sString, $iRepeatCount)
    Local $nResultLen = StringLen($sString) * $iRepeatCount
    If $nResultLen >= 2 ^ 27 Then $nResultLen = 2 ^ 27 - 1 ;Limit String Variant
    Do
        $sString &= $sString
    Until StringLen($sString) >= $nResultLen
    Return StringLeft($sString, $nResultLen)
EndFunc ;==>_StringRepeatEx

I tried to make _StringRepeatEx faster - without consistent success.

On my system, 2^27 string length is the maximum allowed without bombing.

#include <String.au3>

; http://www.autoitscript.com/forum/index.php?showtopic=105167&view=findpost&p=743550
Global $vResultA, $vResultB, $vResultC

$vResultA = ChkTimer(TimerInit(), _StringRepeat("-", 2^20))
ConsoleWrite("_StringRepeat     >>> " & @extended & " ms" & @CRLF)
sleep(50)

$vResultB = ChkTimer(TimerInit(), _StringRepeatEx("-", 2^20))
ConsoleWrite("_StringRepeatEx   >>> " & @extended & " ms" & @CRLF)
sleep(50)

$vResultC = ChkTimer(TimerInit(), _StringRepeatMod("-", 2^20))
ConsoleWrite("_StringRepeatExMod >>> " & @extended & " ms" & @CRLF)
sleep(50)

$vResultD = ChkTimer(TimerInit(), _StringRepeatMod("-", 2^20))
ConsoleWrite("_StringRepeatMod >>> " & @extended & " ms" & @CRLF & @CRLF)
sleep(50)

ConsoleWrite("Is $vResultA = $vResultB? " & ($vResultA = $vResultB) & @CRLF)
ConsoleWrite("Is $vResultA = $vResultC? " & ($vResultA = $vResultC) & @CRLF)
ConsoleWrite("Is $vResultA = $vResultD? " & ($vResultA = $vResultD) & @CRLF)



Func _StringRepeatEx($sString, $iRepeatCount)
    Local $nResultLen = StringLen($sString) * $iRepeatCount
    If $nResultLen >= 2^27 Then $nResultLen = 2^27 - 1 ;Limit String Variant
    Do
    $sString &= $sString
    Until StringLen($sString) >= $nResultLen
    Return StringLeft($sString, $nResultLen)
EndFunc

Func _StringRepeatExMod($sString, $iRepeatCount)
    Local $nResultLen = StringLen($sString) * $iRepeatCount
    If $nResultLen >= 2^27 Then $nResultLen = 2^27 - 1 ;Limit String Variant
    for $x= 1 to Ceiling(Log($iRepeatCount)/ Log(2))
    $sString &= $sString
 next
    Return StringLeft($sString, $nResultLen)
EndFunc

; Modified _StringRepeat from String.au3 include file.
Func _StringRepeatMod($sString, $iRepeatCount)
    ;==============================================
    ; Local Constant/Variable Declaration Section
    ;==============================================
    Local $i = StringLen($sString)
    Local $iLoops = Ceiling(Log(StringLen($sString) * $iRepeatCount)/ Log(2))
    Select
        Case Not StringIsInt($iRepeatCount)
            SetError(1)
            Return ""
        Case StringLen($sString) < 1
            SetError(1)
            Return ""
        Case $iRepeatCount <= 0
            SetError(1)
            Return ""
        case StringLen($sString) * $iRepeatCount >= 2^27 ;Limit String Variant
            $iLoops = Ceiling(Log(2^27 - 1)/ Log(2))
            ContinueCase
        Case Else
            For $iCount = 1 To $iLoops
                $sString &= $sString
            Next
            Return StringLeft($sString, $i * $iRepeatCount)
    EndSelect
EndFunc ;==>_StringRepeat

Func ChkTimer($iTime, $vResult)
    Return SetExtended(TimerDiff($iTime), $vResult)
EndFunc

My results on first run:-

_StringRepeat >>> 2079 ms

_StringRepeatEx >>> 10 ms

_StringRepeatExMod >>> 10 ms

_StringRepeatMod >>> 10 ms

Is $vResultA = $vResultB? True

Is $vResultA = $vResultC? True

Is $vResultA = $vResultD? True

Thanks for sharing.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0