Sign in to follow this  
Followers 0
Chimp

count fast occurence of a char in a (very long) string

12 posts in this topic

#1 ·  Posted (edited)

The little assembly code posted >here by Tekk to count how many @LF there are in a string is very fast.

It can be easly modified to count any other char instead of only a @LF in this way:

#include <Memory.au3>

Local $sString, $char

For $i = 1 To 100000
    $sString &= "This line is line " & $i & @CRLF
Next

$char = "i"

MsgBox(0, 'Count of "' & $char & '"', 'There are ' & StringCountChar($sString, $char) & ' occurrences of the char "' & $char & '"')

Func StringCountChar(ByRef $g_sString, $sCHR)
    Local $pCountLF = _MemVirtualAlloc(Null, 25, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE)
    $sCHR = StringLeft($sCHR, 1)
    DllStructSetData(DllStructCreate("BYTE[25]", $pCountLF), 1, "0x" _
             & "8B4C2404" _     ;~     mov  ecx, dword[esp+04h]
             & "31C0" _     ;~     xor  eax, eax
             & "8A11" _     ;~  @@:mov  dl, byte[ecx]
             & "80FA00" _     ;~     cmp  dl, 00h
             & "7409" _     ;~     je   @f
             & "41" _     ;~     inc  ecx
             & "80FA" & Hex(Asc($sCHR), 2) _     ;~     cmp  dl, NNh <-- modified here
             & "75F3" _     ;~     jne  @b
             & "40" _     ;~     inc  eax
             & "EBF0" _     ;~     jmp  @b
             & "C20400" _     ;~  @@:ret  4
            )
    Local $nResult = DllCallAddress("INT", $pCountLF, "STR", $g_sString)[0]
    _MemVirtualFree($pCountLF, 0, $MEM_RELEASE)
    Return $nResult
EndFunc   ;==>StringCountChar

That's all.

edit:

added ByRef to $g_sString in function

Edited by Chimp
3 people like this

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites



Some would argue this is misusing the language.


_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_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: 04/09/2015

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Some would argue this is misusing the language.

 

 

What is their argument? 

 

Edit: And by Chimp's test 2nd place is 100% slower.  That peaks my curiosity even more as to what the negatives would be, and why there isnt already a UDF of ASM versions of existing string functions that could be used interchangeably for speed benefit.

Edited by boththose

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites

???

$string = "Now is the time for all good men  to come to the aid of their neighbor"
 
$search = "o"
 
StringReplace( $string, $search, " ")
 
MsgBox(0, 0, "Count = " & @extended )

NEWHeader1.png

Share this post


Link to post
Share on other sites

That one is in Chimps test.  And speedwise is not close.


,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites

 

???

$string = "Now is the time for all good men  to come to the aid of their neighbor"
 
$search = "o"
 
StringReplace( $string, $search, " ")
 
MsgBox(0, 0, "Count = " & @extended )

 

using StringReplace is one of the slowest ways against some others as from results of speed test posted >here


small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites

using StringReplace is one of the slowest ways against some others as from results of speed test posted >here

 

Great work by you and UEZ

8)


NEWHeader1.png

Share this post


Link to post
Share on other sites

Crashes for me using x64. Won't work for searching for utf8 characters either.

Share this post


Link to post
Share on other sites

Crashes for me using x64. Won't work for searching for utf8 characters either.

X64 process cannotexecute x86 assembly

Share this post


Link to post
Share on other sites

...... Won't work for searching for utf8 characters either.

 

Yes, you are right, (also stated >here)

This is just a funny, and also a bit instructive, experiment (nothing more) to be eventually used against 8-bit ANSI files/strings (no claims of outclass native functions).

p.s.

>Here another funny snippet by UEZ that seems can handle Wchars.


small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

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