Jump to content

_ByteSuffix replacement ?


Recommended Posts

Hi and thanks for stopping by to read my post.

I'm trying to recreate byte suffix function without a while loop.

This is the _ByteSuffix() function I found on the forums

;Breaks timing of my script.
Func _ByteSuffix($iBytes, $iRound = 2) ; By Spiff59
    Local $A, $aArray[9] = [" B", " KB", " MB", " GB", " TB", " PB", "EB", "ZB", "YB"]

    While $iBytes > 1023
        $A += 1
        $iBytes /= 1024
    WEnd
    Return StringFormat("%." & $iRound & "f %s", $iBytes, $aArray[$A])
EndFunc   ;==>_ByteSuffix

_ByteSuffix function is great but I can't use it in a timing critical situation.

eg: I'm recording to mp3 from WaveIn device, while recording I'm updating a tooltip with how many bytes are written to the harddrive.

As the hours go by and the bytes are now at 400+ MB in size, the _ByteSuffix while loop is causing havoc with my callback function (_ByteSuffix is not called from within my callback).

I can just hard set my size to MB via StringFormat("Size %.2f MB, $bytes/1024/1024) which works without fault, but I did like the _ByteSuffix auto telling the size in B/KB/MB/GB etc as the size increases.

Any other alternatives?

TYIA for any advice

Cheers

Link to comment
Share on other sites

I use _ByteSuffix() quite a bit, that looks like :mellow: but you could look at _WinAPI_StrFormatByteSize() in WinAPIEx.au3 by Yashied.

Edited by guinness

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

Hi and thank you for the input.

The _WinAPI_StrFormatByteSize() function causes my script to crash after a a couple of minutes.

It's not the functions fault, it more that I should run WaveIn processing in a different thread to my script, this way timing wouldn't be as critical.

NVM, I'll just stick with StringFormat("Size %.2f MB", $bytes/1024/1024) for now.

Cheers

Edited by smashly
Link to comment
Share on other sites

OK, I'm sure there is another way to write the function you're having a problem with. But it you're happy then I'm happy.

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

You can speedup the function when you take out the array and make it global and use short variable names:

Global $aA2[9] = [" B", " KB", " MB", " GB", " TB", " PB", "EB", "ZB", "YB"]
$b = 12345678

$rounds = 500000
$t = TimerInit()
For $i = 1 To $rounds
    _ByteSuffix($b)
Next
ConsoleWrite(TimerDiff($t) & " ms" & @CRLF)

$t = TimerInit()
For $i = 1 To $rounds
    _ByteSuffix2($b)
Next
ConsoleWrite(TimerDiff($t) & " ms" & @CRLF)

Func _ByteSuffix($iBytes, $iRound = 2) ; By Spiff59
    Local $A, $aArray[9] = [" B", " KB", " MB", " GB", " TB", " PB", "EB", "ZB", "YB"]
    While $iBytes > 1023
        $A += 1
        $iBytes /= 1024
    WEnd
    Return StringFormat("%." & $iRound & "f %s", $iBytes, $aArray[$A])
EndFunc   ;==>_ByteSuffix

;Breaks timing of my script.
Func _ByteSuffix2($iB, $iR = 2) ; By Spiff59
    Local $A
    While $iB > 1023
        $A += 1
        $iB /= 1024
    WEnd
    Return StringFormat("%." & $iR & "f %s", $iB, $aA2[$A])
EndFunc   ;==>_ByteSuffix

My results:

25205.2352236101 ms

14912.607149138 ms

Maybe it is fast enough this way...

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

StringFormat is really slow. You can speed it up using Round and string concatenation.

Func _ByteSuffix3($iB, $iR = 2)
    Local $A
    While $iB > 1023
        $A += 1
        $iB /= 1024
    WEnd
    Return Round($iB, $iR) & $aA2[$A]
EndFunc   ;==>_ByteSuffix

Results:

...Suffix: 18654.8370617678 ms
...Suffix2: 14830.0579327885 ms
...Suffix3: 4975.75219331219 ms (<!--)

*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

Link to comment
Share on other sites

Hurray, another code optimizing thread. :mellow: Always fun.

Here is also with added 'optimized' (nope), version of _WinAPI_StrFormatByteSize as mentioned above.

ProgAndy version still wins by miles. Also, _WinAPI_StrFormatByteSize prints "1 bytes" where it should be "1 byte".

Global $aA2[9] = [" B", " KB", " MB", " GB", " TB", " PB", "EB", "ZB", "YB"]
$b = 12345678

$rounds = 50000
$t = TimerInit()
For $i = 1 To $rounds
    _ByteSuffix($b)
Next
ConsoleWrite(TimerDiff($t) & " ms" & @CRLF)

$t = TimerInit()
For $i = 1 To $rounds
    _ByteSuffix2($b)
Next
ConsoleWrite(TimerDiff($t) & " ms" & @CRLF)

$t = TimerInit()
For $i = 1 To $rounds
    _ByteSuffix3($b)
Next
ConsoleWrite(TimerDiff($t) & " ms" & @CRLF)

$dll = DllOpen('shlwapi.dll')
$tData = DllStructCreate('wchar[80]')
$t = TimerInit()
For $i = 1 To $rounds
    $Ret = DllCall($dll, 'ptr', 'StrFormatByteSizeW', 'uint64', $i, 'ptr', DllStructGetPtr($tData), 'uint', 80)
    DllStructGetData($tData, 1)
Next
ConsoleWrite(TimerDiff($t) & " ms" & @CRLF)
DllClose($dll)

Func _ByteSuffix($iBytes, $iRound = 2) ; By Spiff59
    Local $A, $aArray[9] = [" B", " KB", " MB", " GB", " TB", " PB", "EB", "ZB", "YB"]
    While $iBytes > 1023
        $A += 1
        $iBytes /= 1024
    WEnd
    Return StringFormat("%." & $iRound & "f %s", $iBytes, $aArray[$A])
EndFunc   ;==>_ByteSuffix

;Breaks timing of my script.
Func _ByteSuffix2($iB, $iR = 2) ; By Spiff59
    Local $A
    While $iB > 1023
        $A += 1
        $iB /= 1024
    WEnd
    Return StringFormat("%." & $iR & "f %s", $iB, $aA2[$A])
EndFunc   ;==>_ByteSuffix

Func _ByteSuffix3($iB, $iR = 2)
    Local $A
    While $iB > 1023
        $A += 1
        $iB /= 1024
    WEnd
    Return Round($iB, $iR) & $aA2[$A]
EndFunc   ;==>_ByteSuffix

Edit: Results are in for same 500,000 iterations as above:

20028.1383262019 ms
16827.4042868478 ms
6079.70133003873 ms <-- ProgAndy
7284.23599763774 ms

But, ProgAndy version crashes when you exceed 10^27 bytes. Solution is to modify array ad infinitum.

Edited by Manadar
Link to comment
Share on other sites

But you are all doing the tests wrong. For example try running ProgAndy's version first and do collect the output string to a variable.

Maybe you'll be surprised by the results.

Interesting. Just changing the order:

6031.79991811802 ms
19238.498480111 ms
16072.157137319 ms
7144.3813019235 ms

First question: Order doesn't matter? Needs further study. Next: Changing script so all is stored in $a, not concatenating or anything. (Same order as above)

6953.32319470158 ms
17841.9247519085 ms
15374.8120518683 ms
7332.00607230976 ms

Another test with concatenation, storing everything to variable $a with &=. After each round I set $a to empty string. This means a forced conversion to string, that's what you meant right?

4429.04618361129 ms
17968.7222606673 ms
15369.7428869558 ms
11236.0574188336 ms <-- !

Very cool! :mellow: Another time changing order:

11230.671685863 ms
20246.0055360915 ms
5049.24105185738 ms
15043.7593068292 ms

You can still see which test is which, though. Maybe order doesn't matter, or did you mean something else? (Or is this coincidentally not the case, but usually is?) I can see why you said that tests were wrong, they clearly were. Depending on test the results can vary wildly. Sometimes even leads you to pick the wrong approach, fortunately in this case that wasn't so.

Edited by Manadar
Link to comment
Share on other sites

Maybe it's processor related thing.

Global $dll = DllOpen('shlwapi.dll')
Global $aA2[9] = [" B", " KB", " MB", " GB", " TB", " PB", "EB", "ZB", "YB"]
$b = 12345678
Global $sResult
$rounds = 50000
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


$sResult = ""
$t = TimerInit()
For $i = 1 To $rounds
    $sResult = _ByteSuffix3($b)
Next
ConsoleWrite(TimerDiff($t) & " ms  $sResult = " & $sResult & @CRLF)


$sResult = ""
$t = TimerInit()
For $i = 1 To $rounds
    $sResult = _ByteSuffix2($b)
Next
ConsoleWrite(TimerDiff($t) & " ms  $sResult = " & $sResult & @CRLF)


$sResult = ""
$t = TimerInit()
For $i = 1 To $rounds
    $sResult = _ByteSuffix($b)
Next
ConsoleWrite(TimerDiff($t) & " ms  $sResult = " & $sResult & @CRLF)


$sResult = ""
$t = TimerInit()
For $i = 1 To $rounds
    $sResult = _ByteSuffix4($b)
Next
ConsoleWrite(TimerDiff($t) & " ms  $sResult = " & $sResult & @CRLF)



;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Func _ByteSuffix($iBytes, $iRound = 1)
    Local $A, $aArray[9] = [" B", " KB", " MB", " GB", " TB", " PB", "EB", "ZB", "YB"]
    While $iBytes > 1023
        $A += 1
        $iBytes /= 1024
    WEnd
    Return StringFormat("%." & $iRound & "f %s", $iBytes, $aArray[$A])
EndFunc   ;==>_ByteSuffix

Func _ByteSuffix2($iB, $iR = 1)
    Local $A
    While $iB > 1023
        $A += 1
        $iB /= 1024
    WEnd
    Return StringFormat("%." & $iR & "f %s", $iB, $aA2[$A])
EndFunc   ;==>_ByteSuffix2

Func _ByteSuffix3($iB, $iR = 1)
    Local $A
    While $iB > 1023
        $A += 1
        $iB /= 1024
    WEnd
    Return Round($iB, $iR) & $aA2[$A]
EndFunc   ;==>_ByteSuffix3

Func _ByteSuffix4($iB)
    Local $Ret = DllCall($dll, "ptr", "StrFormatByteSizeW", "uint64", $iB, "wstr", "", "uint", 16)
    If @error Then Return ""
    Return $Ret[2]
EndFunc   ;==>_ByteSuffix4

>Running:(3.3.7.14):F:\Program Files (x86)\AutoIt3\Beta\autoit3_x64.exe "F:\Users\trancexx\Desktop\New AutoIt v3 Script (1).au3"    
7921.23077094994 ms  $sResult = 11.8 MB
6754.53863549697 ms  $sResult = 11.8  MB
6987.77805559086 ms  $sResult = 11.8  MB
1986.33178239134 ms  $sResult = 11,7 MB

Is your Intel?

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

Maybe it's processor related thing.

>Running:(3.3.7.14):F:\Program Files (x86)\AutoIt3\Beta\autoit3_x64.exe "F:\Users\trancexx\Desktop\New AutoIt v3 Script (1).au3"    
7921.23077094994 ms  $sResult = 11.8 MB
6754.53863549697 ms  $sResult = 11.8  MB
6987.77805559086 ms  $sResult = 11.8  MB
1986.33178239134 ms  $sResult = 11,7 MB

Is your Intel?

Woah, your times. They're very different from mine.

480.896770734076 ms  $sResult = 11.8 MB
1517.20970844942 ms  $sResult = 11.8  MB
1825.6457263765 ms  $sResult = 11.8  MB
870.260536870442 ms  $sResult = 11.7 MB

Yes, it is Intel. Do you know what is so different about them that matter in this case?

Edit: i5 430M

Edited by Manadar
Link to comment
Share on other sites

Woah, your times. They're very different from mine.

480.896770734076 ms  $sResult = 11.8 MB
1517.20970844942 ms  $sResult = 11.8  MB
1825.6457263765 ms  $sResult = 11.8  MB
870.260536870442 ms  $sResult = 11.7 MB

Yes, it is Intel. Do you know what is so different about them that matter in this case?

Edit: i5 430M

Yes, they are. I did what's called "stress testing". It's pushing everything to the max first, thru a period of time, and then run script in that state.

I have a friend who's a true geek and he has a whole story about the differences between AMD and Intel processors behavior under stress. He's saying (if I recall correctly) that AMD will prefer security over speed in stress situations and Intel's processor will be fast even if totally dumb.

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

Hi,

Thank You all for the insight, it's an enjoyable read and test.

I've decided to rework my original code.

I finally knocked the timing issues on the head and no more callback timing issues.

(Supplemented the DllCallbackRegister with a Gui handle and GuiRegisterMsg)

So now _ByteSuffix can take the time it needs without crashing my script, also the gui can be moved or do other things without pausing or dropping recorded data. w00t.

Glad waveInOpen has so many options for callback methods, I've now just about tried them all..lol

All that's left to do is tidy my script up and post it in examples when it's done.

hmm, maybe add a vu bar to show a visual audio db while recording, user settings for the quality of recording and mp3 output, but that's another kettle of fish.

Cheers all

Edited by smashly
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...