Jump to content
kcvinu

How to find how many @LFs in a given text

Recommended Posts

kcvinu

Hi all,

I am in the midle of a string related script. I need to find how many line breakes are there in the given text.  How can i do that. I think i need to use StringRegExp function. Am i right ?


My Contributions

UDF Link Viewer   --- A tool to visit the links of some most important UDFs 

 Includer_2  ----- A tool to type the #include statement automatically 

 Digits To Date  ----- date from 3 integer values

PrintList ----- prints arrays into console for testing.

 Alert  ------ An alternative for MsgBox 

 MousePosition ------- A simple tooltip display of mouse position

GRM Helper -------- A littile tool to help writing code with GUIRegisterMsg function

Access_UDF  -------- An UDF for working with access database files. (.*accdb only)

 

Share this post


Link to post
Share on other sites
Melba23

kcvinu,

No. Just use StringReplace and see what is returned in @extended: :)

#include <MsgBoxConstants.au3>

$sString = "Line 1" & @LF & "Line 2" & @LF & "Line 3"

StringReplace($sString, @LF, "")

MsgBox($MB_SYSTEMMODAL, "Count", @extended)
M23
  • Like 1

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites
mikell

MsgBox($MB_SYSTEMMODAL, "Count", StringSplit($sString, @LF)[0]-1)

:)

Edit

of course if you absolutely want a regex...

MsgBox($MB_SYSTEMMODAL, "Count", UBound(StringRegExp($sString, @LF, 3)))
Edited by mikell
  • Like 1

Share this post


Link to post
Share on other sites
SadBunny

Or...

$sString = "Line 1" & @LF & "Line 2" & @LF & "Line 3"

MsgBox(0, 0, StringLen(StringRegExpReplace($sString, "[^\n]", ""))) ; replace everything that is not a linefeed by an empty string, then shows the length of the resulting string
Edited by SadBunny
  • Like 1

Roses are FF0000, violets are 0000FF... All my base are belong to you.

Share this post


Link to post
Share on other sites
Malkey

And another way.

#include <MsgBoxConstants.au3>

; Based on http://www.autoitscript.com/forum/topic/6330-new-fast-line-counter/page__view__findpost__p__44449

;For file
;$file = "Lines.txt"
;Local $N = FileGetSize($file)
;MsgBox($MB_SYSTEMMODAL, "Count", StringLen(StringAddCR(FileRead($file, $N))) - $N)

;For a string
;$sString = FileRead($file)
$sString = "Line 1" & @CRLF & "Line 2" & @LF & "Line 3"
MsgBox($MB_SYSTEMMODAL, "Count", StringLen(StringAddCR($sString)) - StringLen($sString))
  • Like 1

Share this post


Link to post
Share on other sites
Chimp

I like Melba23's way,
anyway, since some other worse attempt has been posted,
here is another even worst way ..... :P

#include <array.au3>
$sString = "Line 1" & @LF & "Line 2" & @LF & "Line 3"

MsgBox(0, "nr. of @LF", UBound(_ArrayFindAll(StringSplit($sString, "", 2), Chr(10))))
Edited by Chimp
  • Like 1

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
Malkey

After Chimp's post, I realized that most people would not think that the StringAddCR method is the fastest.
Here are my results.

Speed (secs)    Poster      Method
0.32268            Malkey      StringLen(StringAddCR($sString)) - StringLen($sString)
0.55071            Mikell        UBound(StringRegExp($sString, @LF, 3))
0.76448            Mikell        StringSplit($sString, @LF)[0]-1
2.67618            Melba23   StringReplace($sString, @LF, "");  @extended
6.46621            SadBunny StringLen(StringRegExpReplace($sString, "[^n]", ""))
Crashed           Chimp        _ArrayFindAll(StringSplit($sString, "", 2), Chr(10))

The surprises for me was  Mikell's StringRegExp was comparatively fast but can be logically justified, being a simple RE pattern.

And, Melba23's StringReplace - @extended was comparatively slow.

#include <array.au3>
#include <FileConstants.au3>
#include <MsgBoxConstants.au3>

Local Const $sFilePath = @ScriptDir & "\TestFileWrite.txt"

; If file does not exist, create 25mb "TestFileWrite.txt" file.
If FileExists($sFilePath) = 0 Then
    Local $hFileOpen = FileOpen($sFilePath, $FO_APPEND)
    If $hFileOpen = -1 Then
        MsgBox($MB_SYSTEMMODAL, "", "An error occurred when reading the file.")
        Return False
    EndIf
    For $i = 1 To 1000000
        FileWrite($hFileOpen, "This line is line " & $i & @CRLF)
    Next
    FileClose($hFileOpen)
EndIf

$sString = FileRead($sFilePath)
Local $hTimer = TimerInit()

;$a = _ArrayFindAll(StringSplit($sString, "", 2), Chr(10)) ; Crashed
;MsgBox(0, "Chimp", "Time: " & TimerDiff($hTimer)/1000 " Secs" & @CRLF &  UBound($a)

$a = StringLen(StringAddCR($sString)) - StringLen($sString)
MsgBox(0, "Malkey String", "Time: " & Round(TimerDiff($hTimer) / 1000, 5) & " secs" & @CRLF & $a) ; 0.32268 secs

;$N = FileGetSize($sFilePath)
;$a = StringLen(StringAddCR(FileRead($sFilePath))) - $N ; 0.69827 secs
;$a = StringLen(StringAddCR($sString)) - $N             ; 0.32333 secs
;MsgBox(0, "Malkey File ", "Time: " & Round(TimerDiff($hTimer) / 1000, 5) & " secs" & @CRLF & $a)

;$a =  StringLen(StringRegExpReplace($sString, "[^\n]", ""))
;MsgBox(0, "SadBunny ", "Time: " & Round(TimerDiff($hTimer) / 1000, 5) & " secs" & @CRLF & $a) ; 6.46621 secs

;$a =  UBound(StringRegExp($sString, @LF, 3))
;MsgBox(0, "Mikell II ", "Time: " & Round(TimerDiff($hTimer) / 1000, 5) & " secs" & @CRLF & $a) ; 0.55071 secs

;$a =  StringSplit($sString, @LF)[0]-1
;MsgBox(0, "Mikell I ", "Time: " & Round(TimerDiff($hTimer) / 1000, 5) & " secs" & @CRLF & $a) ; 0.76448 secs

;StringReplace($sString, @LF, "")
;$a = @extended
;MsgBox(0, "Melba23 ", "Time: " & Round(TimerDiff($hTimer) / 1000, 5) & " secs" & @CRLF & $a) ; 2.67618 secs

;FileDelete($sFilePath)

Share this post


Link to post
Share on other sites
jchd

How does this compare on your computer?

$hTimer = TimerInit()
StringRegExpReplace($sString, "\n", "\n")
$a =  @extended
MsgBox(0, "jchd ", "Time: " & Round(TimerDiff($hTimer) / 1000, 5) & " secs" & @CRLF & $a)

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites
Malkey

 

How does this compare on your computer?

$hTimer = TimerInit()
StringRegExpReplace($sString, "\n", "\n")
$a =  @extended
MsgBox(0, "jchd ", "Time: " & Round(TimerDiff($hTimer) / 1000, 5) & " secs" & @CRLF & $a)

The fastest speed after several runs was 0.36513 secs. Making it a close second fastest on my Environment(Language:0409  Keyboard:00000409  OS:WIN_7/Service Pack 1  CPU:X64 OS:X64), running 3.3.12.0 AutoIt version.

Using

StringRegExpReplace($sString, "\n", "")

The fastest speed after several runs was 0.32308 secs.

This is getting very close to the speed of the StringAddCR method

Edit The StringAddCR method is based on:

'?do=embed' frameborder='0' data-embedContent>>

Edit2:  I did give this reference in post #5.

 

Edited by Malkey

Share this post


Link to post
Share on other sites
Chimp

my post >#6 was obviously a joke, as stated by the sentence "here is another even worst way"
indeed is the worst of all

anyway are very interesting the surprising performances of the StringAddCR !!

here a time comparison "live"

#include <array.au3>

Local $sString, $hTimer, $aCompetitors[7][2] = [ _
        ["Melba23   ", 0], _
        ["Mikell    ", 0], _
        ["Mikell 2  ", 0], _
        ["SadBunny  ", 0], _
        ["Malkey    ", 0], _
        ["Chimp     ", 0], _
        ["jchd      ", 0]]

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

StringReplace($sString, @LF, "")
$a = @extended
Stopwatch(0, $hTimer, $aCompetitors)
ConsoleWrite(StringFormat("%-20s", $aCompetitors[0][0]) & @TAB & $aCompetitors[0][1] & " secs" & @TAB & $a & @CRLF)

$a = StringSplit($sString, @LF)[0] - 1
Stopwatch(1, $hTimer, $aCompetitors)
ConsoleWrite(StringFormat("%-20s", $aCompetitors[1][0]) & @TAB & $aCompetitors[1][1] & " secs" & @TAB & $a & @CRLF)

$a = UBound(StringRegExp($sString, @LF, 3))
Stopwatch(2, $hTimer, $aCompetitors)
ConsoleWrite(StringFormat("%-20s", $aCompetitors[2][0]) & @TAB & $aCompetitors[2][1] & " secs" & @TAB & $a & @CRLF)

$a = StringLen(StringRegExpReplace($sString, "[^\n]", ""))
Stopwatch(3, $hTimer, $aCompetitors)
ConsoleWrite(StringFormat("%-20s", $aCompetitors[3][0]) & @TAB & $aCompetitors[3][1] & " secs" & @TAB & $a & @CRLF)

$a = StringLen(StringAddCR($sString)) - StringLen($sString)
Stopwatch(4, $hTimer, $aCompetitors)
ConsoleWrite(StringFormat("%-20s", $aCompetitors[4][0]) & @TAB & $aCompetitors[4][1] & " secs" & @TAB & $a & @CRLF)

$a = UBound(_ArrayFindAll(StringSplit($sString, "", 2), Chr(10))) ; Crashed
Stopwatch(5, $hTimer, $aCompetitors)
ConsoleWrite(StringFormat("%-20s", $aCompetitors[5][0]) & @TAB & $aCompetitors[5][1] & " secs" & @TAB & $a & @CRLF)

StringRegExpReplace($sString, "\n", "\n")
$a = @extended
Stopwatch(6, $hTimer, $aCompetitors)
ConsoleWrite(StringFormat("%-20s", $aCompetitors[6][0]) & @TAB & $aCompetitors[6][1] & " secs" & @TAB & $a & @CRLF)

_ArraySort($aCompetitors, 0, 0, 0, 1)
_ArrayDisplay($aCompetitors, "Results")

Func Stopwatch($iCompetitor, ByRef $hTimer, ByRef $aCompetitors)
    $aCompetitors[$iCompetitor][1] = Round(TimerDiff($hTimer) / 1000, 5)
    $hTimer = TimerInit()
EndFunc   ;==>Stopwatch


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
Tekk

Senseless unless the string is very long and also not really AutoIt but…

#include <Memory.au3>

Func StringCountLF($sString)
    Local $pCountLF = _MemVirtualAlloc(Null, 25, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE)

    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
            & "80FA0A"   _     ;~     cmp  dl, 0Ah
            & "75F3"     _     ;~     jne  @b
            & "40"       _     ;~     inc  eax
            & "EBF0"     _     ;~     jmp  @b
            & "C20400"   _     ;~  @@:ret  4
    )

    Local $nResult = DllCallAddress("INT", $pCountLF, "STR", $sString)[0]

    _MemVirtualFree($pCountLF, 0, $MEM_RELEASE)

    Return $nResult
EndFunc
Edited by Tekk
  • Like 1

Share this post


Link to post
Share on other sites
Chimp

 

Senseless unless the string is very long and also not really AutoIt but…

#include <Memory.au3>

Func StringCountLF($sString)
    Local $pCountLF = _MemVirtualAlloc(Null, 25, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE)

    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
            & "80FA0A"   _     ;~     cmp  dl, 0Ah
            & "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

 

ha, assembly version!

how must this be used?

my test only returns 0

#include <Memory.au3>

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

ConsoleWrite(StringCountLF($sString)&@CRLF)

Func StringCountLF($sString)

    Local $g_sString ; <-- added to avoid following error
    ; "D:\Autoit\Test\1.au3" (28) : ==> Variable used without being declared.:
    ; Local $nResult = DllCallAddress("INT", $pCountLF, "STR", $g_sString)[0]
    ; Local $nResult = DllCallAddress("INT", $pCountLF, "STR", ^ ERROR

    Local $pCountLF = _MemVirtualAlloc(Null, 25, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE)

    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
            & "80FA0A"   _     ;~     cmp  dl, 0Ah
            & "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

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
mikell

The error is caused by a typo, it should be like this

Func StringCountLF($g_sString)

Share this post


Link to post
Share on other sites
Chimp

 

The error is caused by a typo, it should be like this

Func StringCountLF($g_sString)

 

ha yes, you are right, now it works, thanks mikell

here a new race with the new competitor

p.s.

(chimp has retired from competition. Disqualified! : )

#include <array.au3>
#include <Memory.au3>

Local $sString, $hTimer, $aCompetitors[7][2] = [ _
        ["Melba23   ", 0], _
        ["Mikell    ", 0], _
        ["Mikell 2  ", 0], _
        ["SadBunny  ", 0], _
        ["Malkey    ", 0], _
        ["jchd      ", 0], _
        ["Tekk      ", 0]]

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

StringReplace($sString, @LF, "")
$a = @extended
Stopwatch(0, $hTimer, $aCompetitors)
ConsoleWrite(StringFormat("%-20s", $aCompetitors[0][0]) & @TAB & $aCompetitors[0][1] & " secs" & @TAB & $a & @CRLF)

$a = StringSplit($sString, @LF)[0] - 1
Stopwatch(1, $hTimer, $aCompetitors)
ConsoleWrite(StringFormat("%-20s", $aCompetitors[1][0]) & @TAB & $aCompetitors[1][1] & " secs" & @TAB & $a & @CRLF)

$a = UBound(StringRegExp($sString, @LF, 3))
Stopwatch(2, $hTimer, $aCompetitors)
ConsoleWrite(StringFormat("%-20s", $aCompetitors[2][0]) & @TAB & $aCompetitors[2][1] & " secs" & @TAB & $a & @CRLF)

$a = StringLen(StringRegExpReplace($sString, "[^\n]", ""))
Stopwatch(3, $hTimer, $aCompetitors)
ConsoleWrite(StringFormat("%-20s", $aCompetitors[3][0]) & @TAB & $aCompetitors[3][1] & " secs" & @TAB & $a & @CRLF)

$a = StringLen(StringAddCR($sString)) - StringLen($sString)
Stopwatch(4, $hTimer, $aCompetitors)
ConsoleWrite(StringFormat("%-20s", $aCompetitors[4][0]) & @TAB & $aCompetitors[4][1] & " secs" & @TAB & $a & @CRLF)

StringRegExpReplace($sString, "\n", "\n")
$a = @extended
Stopwatch(5, $hTimer, $aCompetitors)
ConsoleWrite(StringFormat("%-20s", $aCompetitors[5][0]) & @TAB & $aCompetitors[5][1] & " secs" & @TAB & $a & @CRLF)

$a = StringCountLF($sString)
Stopwatch(6, $hTimer, $aCompetitors)
ConsoleWrite(StringFormat("%-20s", $aCompetitors[6][0]) & @TAB & $aCompetitors[6][1] & " secs" & @TAB & $a & @CRLF)


_ArraySort($aCompetitors, 0, 0, 0, 1)
_ArrayDisplay($aCompetitors, "Results")

Func Stopwatch($iCompetitor, ByRef $hTimer, ByRef $aCompetitors)
    $aCompetitors[$iCompetitor][1] = Round(TimerDiff($hTimer) / 1000, 5)
    $hTimer = TimerInit()
EndFunc   ;==>Stopwatch

Func StringCountLF($g_sString)
    Local $pCountLF = _MemVirtualAlloc(Null, 25, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE)
    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
            & "80FA0A"   _     ;~     cmp  dl, 0Ah
            & "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
  • Like 1

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
kcvinu

Hi All,

Thanks for the reply. I am sorry, i can't access to internet in last few days. I will sure inform you about which method suits for me. 


My Contributions

UDF Link Viewer   --- A tool to visit the links of some most important UDFs 

 Includer_2  ----- A tool to type the #include statement automatically 

 Digits To Date  ----- date from 3 integer values

PrintList ----- prints arrays into console for testing.

 Alert  ------ An alternative for MsgBox 

 MousePosition ------- A simple tooltip display of mouse position

GRM Helper -------- A littile tool to help writing code with GUIRegisterMsg function

Access_UDF  -------- An UDF for working with access database files. (.*accdb only)

 

Share this post


Link to post
Share on other sites
UEZ

I shortened the ASM code by 3 bytes (5 bytes are possible be replacing add with inc but add is faster or even more is possible):

 

#include <array.au3>
#include <Memory.au3>

Local $sString, $hTimer, $aCompetitors[7][2] = [ _
        ["Melba23   ", 0], _
        ["Mikell    ", 0], _
        ["Mikell 2  ", 0], _
        ["Malkey    ", 0], _
        ["jchd      ", 0], _
        ["Tekk      ", 0], _
        ["UEZ       ", 0]]

Local $iLines = 1000000
For $i = 1 To $iLines
    $sString &= "This line is line " & $i & @CRLF
Next
ConsoleWrite($iLines & " lines have been created." & @CRLF)

$hTimer = TimerInit()

StringReplace($sString, @LF, "")
$a = @extended
Stopwatch(0, $hTimer, $aCompetitors)
ConsoleWrite(StringFormat("%-20s", $aCompetitors[0][0]) & @TAB & $aCompetitors[0][1] & " secs" & @TAB & $a & @CRLF)

$a = StringSplit($sString, @LF)[0] - 1
Stopwatch(1, $hTimer, $aCompetitors)
ConsoleWrite(StringFormat("%-20s", $aCompetitors[1][0]) & @TAB & $aCompetitors[1][1] & " secs" & @TAB & $a & @CRLF)

$a = UBound(StringRegExp($sString, @LF, 3))
Stopwatch(2, $hTimer, $aCompetitors)
ConsoleWrite(StringFormat("%-20s", $aCompetitors[2][0]) & @TAB & $aCompetitors[2][1] & " secs" & @TAB & $a & @CRLF)

$a = StringLen(StringAddCR($sString)) - StringLen($sString)
Stopwatch(3, $hTimer, $aCompetitors)
ConsoleWrite(StringFormat("%-20s", $aCompetitors[3][0]) & @TAB & $aCompetitors[3][1] & " secs" & @TAB & $a & @CRLF)

StringRegExpReplace($sString, "\n", "\n")
$a = @extended
Stopwatch(4, $hTimer, $aCompetitors)
ConsoleWrite(StringFormat("%-20s", $aCompetitors[4][0]) & @TAB & $aCompetitors[4][1] & " secs" & @TAB & $a & @CRLF)

$a = StringCountLF($sString)
Stopwatch(5, $hTimer, $aCompetitors)
ConsoleWrite(StringFormat("%-20s", $aCompetitors[5][0]) & @TAB & $aCompetitors[5][1] & " secs" & @TAB & $a & @CRLF)

$a = StringCountLF2($sString)
Stopwatch(6, $hTimer, $aCompetitors)
ConsoleWrite(StringFormat("%-20s", $aCompetitors[6][0]) & @TAB & $aCompetitors[6][1] & " secs" & @TAB & $a & @CRLF)

_ArraySort($aCompetitors, 0, 0, 0, 1)
_ArrayDisplay($aCompetitors, "Results")

Func Stopwatch($iCompetitor, ByRef $hTimer, ByRef $aCompetitors)
    $aCompetitors[$iCompetitor][1] = Round(TimerDiff($hTimer) / 1000, 5)
    $hTimer = TimerInit()
EndFunc   ;==>Stopwatch

Func StringCountLF($g_sString)
    Local $pCountLF = _MemVirtualAlloc(Null, 25, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE)
    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
            & "80FA0A"   _     ;~     cmp  dl, 0Ah
            & "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

Func StringCountLF2($g_sString)
    Local $tCodeBuffer = DllStructCreate("byte ASM[22]")
    $tCodeBuffer.ASM = "0x" & _
                       "8B742404" & _ ;mov esi, dword[esp+4] -> get start address (pointer) of the string
                       "31DB" & _ ;xor ebx, ebx -> set ebx = 0
                       "AC" & _ ;lodsb ebx -> load char from [esi] to al register as byte and increment esi by one
                       "3C00" & _ ;cmp al, 0 -> is char = 0
                       "7409" & _ ;jz _end -> if yes then jump to xchange and exit
                       "3C0A" & _ ;cmp al, 0Ah -> if not compare it with @lf char
                       "75F7" & _ ;jne lodsb -> if not @lf load next byte from string
                       "83C301" & _ ;add ebx, 1 -> if yes increase ebx by one -> ebx += 1 (add is faster then inc)
                       "EBF2" & _ ;jmp lodsb -> load next byte from string
                       "93" & _ ;xchg eax, ebx -> result is in ebx but return value is always eax -> swap eax with ebx
                       "C3" ;return eax
    Return DllCall("user32.dll", "uint", "CallWindowProcW", "ptr", DllStructGetPtr($tCodeBuffer), "str", $g_sString, "int", 0, "int", 0, "int", 0)[0]
EndFunc
 

1.000.000 lines will be generated.

 

 

PS: I'm learning ASM!

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites
SorryButImaNewbie

Threads like this why I love to read the forums even without specific questions or anything :D

  • Like 1

Share this post


Link to post
Share on other sites
Chimp

I shortened the ASM code by 3 bytes (5 bytes are possible be replacing add with inc but add is faster or even more is possible):

 

.....

 

 

PS: I'm learning ASM!

 

 

... I get following result, it seems your asm has some issue it returns too quickly and returns 0

Melba23                 0.60178 secs   75000

Mikell                  0.17548 secs   75000

Mikell 2                0.12632 secs   75000

Malkey                  0.0716 secs    75000

jchd                    0.08136 secs   75000

Tekk                    0.0305 secs    75000

UEZ                     0.0002 secs    0

p.s.

shorten to only 75000 lines for a quick test

Edited by Chimp

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
UEZ

What CPUs are you using?

My results:

 

Melba23                 20.77734 secs   7500000
Mikell                  8.47381 secs    7500000
Mikell 2                6.52575 secs    7500000
Malkey                  3.21329 secs    7500000
jchd                    3.67057 secs    7500000
Tekk                    1.37152 secs    7500000
UEZ                     1.34916 secs    7500000

Melba23                 2.68555 secs    1000000
Mikell                  1.09079 secs    1000000
Mikell 2                0.85604 secs    1000000
Malkey                  0.40858 secs    1000000
jchd                    0.46289 secs    1000000
Tekk                    0.17010 secs    1000000
UEZ                     0.16663 secs    1000000
My CPU:

Intel® Core i5-4300U CPU @ 1.90GHz

Instructions sets MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, EM64T, VT-x, AES, AVX, AVX2, FMA3

The result for both ASM code should be more or less the same!

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

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

  • Similar Content

    • Miliardsto
      By Miliardsto
      I got that func
      Func makeHelpImgGUI($title,$width,$height,$img) $img = GUICtrlCreatePic("",20,40,$width,$height) _ResourceSetImageToCtrl($img, "HERE") EndFunc and I call this func like that
      makeHelpImgGUI("Image",1190, 800,$SETTINGS_JPG)  
      so what is the problem in the parameter where is - "HERE" I need value of img but passed as string
      so $img = $SETTINGS_JPG and how make it "SETTINGS_JPG"
       
      I tried something like that but not work
      Func makeHelpImgGUI($title,$width,$height,$img) $name_str = String($img) $name_str = StringTrimLeft ($name_str, 1 ) $img = GUICtrlCreatePic("",20,40,$width,$height) _ResourceSetImageToCtrl($img, $name_str) EndFunc  
    • liagason
      By liagason
      Hello everyone,
      How can I display in ascending  sequence some numbers stored in a string variable?
      $str = "18,03,48,23" MsgBox(0,"test",$str) I would like it to display "03,18,23,48"
    • Rskm
      By Rskm
      Hi, I have the following line in a text file 'input.txt'. I know the line number - say '6'. I wish to replace the text 'WWW' in the below line with a random number (I can generate that with random()).
      WERIS  WWWJP   3.83  8.330  1.000                1097.RAXX 
      The WWW is a 3 digit integer (could be any number between 0 to 999), I can use stringtrimleft and get the numerical value of WWW in this file
      so, basically, I know the string to replace (ie; WWW stored in a variable), I know the line number to work on and the file location/name and the replacement variable (through random()). My requirement is to fill that 3 spaces with my random number (which Is a integer between 1 and 999)
      please put ur suggestions
       
    • nacerbaaziz
      By nacerbaaziz
      Hello Members of this best Forum
      i have a question please
      for example if i have a long string
      and i want to extract a text between two tag
      what i can do to make that?
      note :
      i know that there is a
      StringRegExp function
      it's do that work
      but it result is be as an array
      i want the result to be a string
      is there any function on autoit can do that?
      Thanks in advance.
    • mistersquirrle
      By mistersquirrle
      Hello!
       
      I wrote myself a script to follow Google Maps Polyline encoding steps: https://developers.google.com/maps/documentation/utilities/polylinealgorithm, and that works (although I think that it's a bit janky), but now I'm having issues getting the output.
       
      When I run the script, all the points come out correctly in the console, and even when they're the only things that I log, it displays them fine. However, I'm adding each point into a variable to return all of them at once at the end, fully formatted, and it's only taking the very first point. I can't figure out what I'm doing wrong, as it seems fine.
       
      When run with the default value, it should output this at the end: Custom Polygon: _p~iF~ps|U_ulLnnqC_mqNvxq`@
      But instead I'm just getting this: Custom Polygon: _p~iF
       
      I know that it's reaching the string combination lines because it's logging the data before it (and even if a put log AFTER the $sPolygon &= $aPoints[0], it's logged fine).
       
      Here's my full code (problem is lines ~209 - 234, search "$sPolygon &= $aPoints[1]"):
      #include <Array.au3> #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> _PolyGUI() Func _PolyGUI() #Region ### START Koda GUI section ### Form= $hInputGUI = GUICreate("Lat Long encoder", 403, 301, 192, 124) GUISetFont(8, 400, 0, "Consolas") GUICtrlCreateLabel("Input polygon points here, format as:", 8, 8, 263, 19) GUICtrlSetFont(-1, 10, 800, 0, "Consolas") GUICtrlCreateLabel("Lat Long - Single point", 8, 24, 142, 17) GUICtrlCreateLabel("Lat Long, Lat Long, Lat Long - Multiple points", 8, 40, 280, 17) Local $sPoints = GUICtrlCreateEdit("", 8, 64, 385, 201, BitOR($ES_WANTRETURN, $WS_VSCROLL)) GUICtrlSetData(-1, "38.5 -120.2, 40.7 -120.95, 43.252 -126.453") GUICtrlSetFont(-1, 10, 400, 0, "Consolas") $bOK = GUICtrlCreateButton("bOK", 16, 272, 123, 25) GUICtrlSetFont(-1, 12, 800, 0, "Consolas") $bCancel = GUICtrlCreateButton("bCancel", 304, 272, 75, 25) GUICtrlSetFont(-1, 12, 800, 0, "Consolas") GUISetState(@SW_SHOW, $hInputGUI) #EndRegion ### END Koda GUI section ### While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $bCancel Exit Case $bOK $sPoints = GUICtrlRead($sPoints) GUISetState(@SW_HIDE, $hInputGUI) _GetPoly($sPoints, True) ExitLoop EndSwitch Sleep(10) WEnd EndFunc ;==>_PolyGUI ;https://developers.google.com/maps/documentation/utilities/polylinealgorithm ;https://app.dsmobileidx.com/api/DescribeSearchForLinkId?linkId=469787 ; Note that this will only really work inside the US (this side of the World), as it's assuming any negative is the Longitude ;https://gist.github.com/ismaels/6636986 - decoder ;Using: 41.83162 -87.64696 ; Expected: sfi~F np}uO ; Actual: sfi~f np}uo ; If we remove 32 from the last ASCII code, since the last bit chunk is 0, we get the correct case/ characters ; We need to run this logic back through all the indexes though and do this to all that that <= 63 ;LinkId=469787 ; Expected: q{`aHpa_iVi[kp@}`Aa{@e[eCoqBbAyc@iRy{@g_@mz@|gA{eAh~@Vf~Etv@gB~p@gQ`^yg@~p@ekAldA{KfFxIrJ^pO~Mtl@dPrJnUz[nSpo@wf@fc@yw@n@ob@ ; Actual: s{`aHpa_iVg[kp@}`Aa{@g[gCmqBbA{c@iRy{@e_@kz@|gA{eAh~@Td~Evv@gB|p@gQb^wg@|p@ekAndA{KfFvIpJ`@rO~Mrl@dPrJnU|[lSpo@wf@dc@yw@n@mb@ ; I assume that this is because of bad data, the points have repeating 9's and 0's, which looks fishy. The polygon is (very) close, but not quite the same. Func _GetPoly($sPoints, $bLog = False) Local $timer = TimerInit(), $sConsole[11] Local $sPolygon = "" ; Step 1, take the initial signed value: Local $aCoords = StringRegExp($sPoints, "(-*?\d*\.\d*) (-*?\d*\.\d*)", 3), $aPoints[2] ;~ _ArrayDisplay($aCoords) If $bLog Then _Log(_ArrayToString($aCoords)) For $c = 0 To (UBound($aCoords) - 1) Step 2 ;~ If $bLog Then _Log($c) If $c = 0 Then $aPoints[0] = $aCoords[$c] $aPoints[1] = $aCoords[$c + 1] Else $aPoints[0] = $aCoords[$c] - $aCoords[$c - 2] $aPoints[1] = $aCoords[$c + 1] - $aCoords[$c - 1] EndIf If $bLog Then _Log("- Step 1, take the initial signed value:") _Log(" " & $aPoints[0]) _Log(" " & $aPoints[1]) EndIf ; Step 2, multiply each by 1e5, and round $aPoints[0] = Round($aPoints[0] * 1e5, 0) $aPoints[1] = Round($aPoints[1] * 1e5, 0) If $bLog Then _Log("- Step 2, multiply each by 1e5, and round") _Log(" " & $aPoints[0]) _Log(" " & $aPoints[1]) EndIf ; Step 3, convert Decimal to Binary, using two's complement for negatives. Padded to 32 bits $aPoints[0] = _NumberToBinary($aPoints[0]) $aPoints[1] = _NumberToBinary($aPoints[1]) If $bLog Then _Log("- Step 3, convert Decimal to Binary, using two's complement for negatives. Padded to 32 bits") _Log(" " & $aPoints[0]) _Log(" " & $aPoints[1]) EndIf ; Step 4, left-shifted 1 bit $aPoints[0] = StringTrimLeft($aPoints[0], 1) & "0" $aPoints[1] = StringTrimLeft($aPoints[1], 1) & "0" If $bLog Then _Log("- Step 4, left-shifted 1 bit") _Log(" " & $aPoints[0]) _Log(" " & $aPoints[1]) EndIf ; Step 5, if negative, invert binary If $c = 0 Then If $aCoords[$c] < 0 Then $aPoints[0] = _InvertBinary($aPoints[0]) If $aCoords[$c + 1] < 0 Then $aPoints[1] = _InvertBinary($aPoints[1]) Else If $aCoords[$c] - $aCoords[$c - 2] < 0 Then $aPoints[0] = _InvertBinary($aPoints[0]) If $aCoords[$c + 1] - $aCoords[$c - 1] < 0 Then $aPoints[1] = _InvertBinary($aPoints[1]) EndIf If $bLog Then _Log("- Step 5, if negative, invert binary") _Log(" " & $aPoints[0]) _Log(" " & $aPoints[1]) EndIf Local $aChunks[2][6], $0x20 For $i = 0 To 1 $0x20 = "1" ; This is out BitOR flag, 0x20 BitOR'd onto our 5-bit chunks is always 1*****, except the last chunk $sConsole[5] = "" ; Clearing console variables $sConsole[6] = "" $sConsole[7] = "" $sConsole[8] = "" $sConsole[9] = "" For $j = 0 To 5 ;There will always be 6 chunks ; Step 6 & 7, break into 5-bit chunks, and reverse order $aChunks[$i][$j] = StringTrimLeft($aPoints[$i], StringLen($aPoints[$i]) - 5) ; This splits into 5-bit chunks in reverse order, doing 6 & 7 in one operation ;~ If $bLog Then _Log(" " & $aPoints[$i]) ;~ If $bLog Then _Log(" " & StringLen($aPoints[$i])) ;~ If $bLog Then _Log(" " & StringTrimLeft($aPoints[$i], StringLen($aPoints[$i]) - 5)) ;~ If $bLog Then _Log(" " & $aChunks[$i][$j]) ; Here we consume the original binary string, so the next loop gets the correct next 5-bit chunk $aPoints[$i] = StringTrimRight($aPoints[$i], 5) $sConsole[5] &= $aChunks[$i][$j] & " " ; Once consumed, if the remaining length isn't enough for another bit chunk, switch 0x20 to 0 (no following chunks) If StringLen($aPoints[$i]) <= 5 Then $0x20 = "0" ; Step 8, BitOR 100000 (0x20) to our 5-bit chunks (effectively) $aChunks[$i][$j] = $0x20 & $aChunks[$i][$j] $sConsole[7] &= $aChunks[$i][$j] & " " ; Step 9, converting the chunk from Binary back to Decimal $aChunks[$i][$j] = _BinaryToDec($aChunks[$i][$j]) $sConsole[8] &= $aChunks[$i][$j] & " " ; Step 10, adding 63 to decimal values $aChunks[$i][$j] += 63 $sConsole[9] &= $aChunks[$i][$j] & " " If StringLen($aPoints[$i]) < 5 Then ExitLoop Next If $bLog Then _Log("- Step 6 & 7 (part " & $i & "), break into 5-bit chunks, and reverse order") _Log(" " & $sConsole[5]) _Log("- Step 8 (part " & $i & "), BitOR 100000 (0x20) to our 5-bit chunks (effectively)") _Log(" " & $sConsole[7]) _Log("- Step 9 (part " & $i & "), converting the chunk from Binary back to Decimal") _Log(" " & $sConsole[8]) _Log("- Step 10 (part " & $i & "), adding 63 to decimal values") _Log(" " & $sConsole[9]) EndIf Next Local $aASCII[0] For $i = 0 To 1 Dim $aASCII[0] ; Reset ASCII array For $j = 0 To (UBound($aChunks, 2) - 1) ; For both chunk sets ReDim $aASCII[UBound($aASCII) + 1] ; Add an index for the ASCII array If $aChunks[$i][$j] = "" Or $aChunks[$i][$j] <= 63 Then ; If the chunk is not useful $l = $j For $k = $l To 1 Step -1 If $aChunks[$i][$k] = "" Or $aChunks[$i][$k] <= 63 Or $aASCII[$k] <= 63 Then $aASCII[$k - 1] -= 32 If $aASCII[$k - 1] <= 63 Then _ArrayDelete($aASCII, $k - 1) Else ExitLoop EndIf Next ExitLoop EndIf $aASCII[$j] = Int($aChunks[$i][$j]) Next ;Step 11, convert each value to ASCII equivalent For $k = UBound($aASCII) - 1 To 0 If $aASCII[$k] <= 63 Or $aASCII[$k] = "" Then ReDim $aASCII[UBound($aASCII) - 1] Else ExitLoop EndIf Next $aPoints[$i] = StringFromASCIIArray($aASCII, 0, -1, 0) Next If $bLog Then _Log("- Step 11, convert each value to ASCII equivalent, finished") If $aCoords[$c] <= 0 Then ;@CRLF & " " & If $bLog Then _Log($aPoints[1]) _Log($aPoints[0]) _Log("Next set") EndIf $sPolygon &= $aPoints[1] $sPolygon &= $aPoints[0] Else If $bLog Then _Log($aPoints[0]) _Log($aPoints[1]) _Log("Next set") EndIf $sPolygon &= $aPoints[0] $sPolygon &= $aPoints[1] EndIf Next If $bLog Then _Log("Custom Polygon: " & $sPolygon) _Log(TimerDiff($timer) & @CRLF) EndIf Return $sPolygon EndFunc ;==>_GetPoly Func _NumberToBinary($iNumber) Local $sBinString = "" ; Maximum 32-bit # range is -2147483648 to 2147483647 If $iNumber < -2147483648 Or $iNumber > 2147483647 Then Return SetError(1, 0, "") ; Convert to a 32-bit unsigned integer. We can't work on signed #'s $iUnsignedNumber = BitAND($iNumber, 0x7FFFFFFF) ; Cycle through each bit, shifting to the right until 0 Do $sBinString = BitAND($iUnsignedNumber, 1) & $sBinString $iUnsignedNumber = BitShift($iUnsignedNumber, 1) Until Not $iUnsignedNumber ; Was it a negative #? Put the sign bit on top, and pad the bits that aren't set If $iNumber < 0 Then Return '1' & StringRight("000000000000000000000000000000" & $sBinString, 31) ; Always return 32 bit binaries If StringLen($sBinString) < 32 Then Return StringRight("0000000000000000000000000000000" & $sBinString, 32) Return $sBinString EndFunc ;==>_NumberToBinary Func _BinaryToDec($sBinary) Local Const $aPower[8] = [128, 64, 32, 16, 8, 4, 2, 1] Local $iDec If StringRegExp($sBinary, "[0-1]") Then If StringLen($sBinary) < 8 Then Do $sBinary = "0" & $sBinary Until StringLen($sBinary) = 8 EndIf $aBinary = StringSplit($sBinary, "", 2) For $i = 0 To UBound($aBinary) - 1 ;~ $aBinary[$i] = $aBinary[$i] * $aPower[$i] $iDec += $aBinary[$i] * $aPower[$i] Next Return $iDec Else Return SetError(0, 0, "Not a binary string") EndIf EndFunc ;==>_BinaryToDec Func _InvertBinary($iNumber) ;~ ConsoleWrite(@CRLF & $iNumber) Local $sNumber $aNumber = StringSplit($iNumber, "") For $i = 1 To $aNumber[0] If $aNumber[$i] = 0 Then $aNumber[$i] = 1 ElseIf $aNumber[$i] = 1 Then $aNumber[$i] = 0 Else Return SetError(0, 0, "Not a binary number") EndIf $sNumber &= String($aNumber[$i]) Next Return $sNumber EndFunc ;==>_InvertBinary Func _Log($data) ;~ Local Static $LogEnable = True ConsoleWrite(@CRLF & @HOUR & ":" & @MIN & "." & @SEC & " " & $data) LogData(@HOUR & ":" & @MIN & "." & @SEC & " " & $data, "logs/LOGFILE.txt") EndFunc ;==>_Log Func LogData($text, $File = "logs/LOGFILE.txt") Global $LogFile = "" If $LogFile = "" Then $LogFile = FileOpen($File, 9) OnAutoItExitRegister(CloseLog) EndIf FileWriteLine($LogFile, $text) EndFunc ;==>LogData Func CloseLog() If $LogFile <> "" Then _Log("Closing LoD script" & @CRLF) FileClose($LogFile) EndIf EndFunc ;==>CloseLog  
      I've tried:
      $sPolygon &= $aPoints[0] & $aPoints[1] ;---- $sPolygon = $sPolygon & $aPoints[0] & $aPoints[1] ;---- $sPolygon = $sPolygon & String($aPoints[0] & $aPoints[1]) ;---- $sPolygon = String($sPolygon) & String($aPoints[0]) & String($aPoints[1]) ;---- $sPolygon &= $aPoints[1] $sPolygon &= $aPoints[0] ;----  
      I'm sure it's something basic that I'm overlooking, but I don't understand why it's not combining the strings. 
      Also, unrelated, why doesn't $LogFile = FileOpen($File, 9) create the directory/ file if they don't exist? 9 should be $FO_CREATEPATH (8) + $FO_APPEND (1)?
      Thanks!
×