Page 1 of 1

Performance anomaly in Win32-Ascii (ReplaceString()?)

Posted: Fri Nov 13, 2015 11:29 am
by Keya
hello, tested in 5.31 and 5.40 LTS, there is a strange performance anomaly which seems to be in ReplaceString() although not 100% sure, and only Windows, only 32-bit, and only Ascii compiled:

Code: Select all

NumLoops.i = 10000

For i = 1 To 2000: sBase.s + "one two  three   four    five     six      seven       eight        nine         end": Next i  ;168kb

Time1 = ElapsedMilliseconds()
For i = 1 To NumLoops
  sTest.s = sBase
  Repeat
    If FindString(sTest, "  ") = 0: Break: EndIf
    sTest.s = ReplaceString(sTest, "  ", " ")
  ForEver
Next i
Time2 = ElapsedMilliseconds()

MessageRequester("Done", "Time=" + Str(Time2-Time1) + #TAB$ + StrF((Time2-Time1)/NumLoops) + "ms/call")
Timing results fastest to slowest (all on exact same system/CPU):
Lnx-32-Asc: Time=21701 2.1700999737ms/call
Lnx-64-Asc: Time=21729 2.1728999615ms/call
Lnx-64-Uni: Time=23283 2.3282999992ms/call
OSX-64-Asc: Time=23788 2.3787999153ms/call
Win-64-Asc: Time=25514 2.5513999462ms/call
Lnx-32-Uni: Time=25701 2.5701000690ms/call
Win-64-Uni: Time=28893 2.8893001080ms/call
OSX-64-Uni: Time=32625 3.2625000477ms/call
Win-32-Uni: Time=34212 3.4212000370ms/call
Win-32-Asc: Time=84934 8.4933996201ms/call

Re: Performance anomaly in Win32-Ascii (ReplaceString()?)

Posted: Fri Nov 13, 2015 5:07 pm
by kenmo
I only tested on one Win/PB configuration, but I don't see much difference between ASCII and Unicode.
Debugger OFF
Asc 42058
Uni 44564

Debugger ON (do not trust!)
Asc 43438
Uni 44720
Tested on Win-32 (Windows 7) with PB 5.40.

Re: Performance anomaly in Win32-Ascii (ReplaceString()?)

Posted: Fri Nov 13, 2015 10:43 pm
by Amilcar Matos
I suggest that you repeat the test; but first extract the string building loop out of the test loop.!

Code: Select all

EnableExplicit

Define sTest.s
Define sBase.s
Define NumLoops.l
Define i.l
Define Time1.l
Define Time2.l
#OneSpace = " "
#TwoSpace = "  "

; build the base string
For i = 1 To 2000
  sBase = sBase + "one two  three   four    five     six      seven       eight        nine         end"
Next i  ;168kb

NumLoops = 100
Time1 = ElapsedMilliseconds()
sTest = #NULL$
; build the test string
For i = 1 To NumLoops
  sTest = sTest + sBase
Next i
Time2 = ElapsedMilliseconds()
MessageRequester("Done", "Time=" + StrF(Time2 - Time1) + 
                         #TAB$ + StrF((Time2 - Time1)/NumLoops) + "ms/call" + #LF$ +
                         "Len(Test) = " + Str(Len(sTest)))

; test the replace string command
Time1 = ElapsedMilliseconds()
Repeat
  If FindString(sTest, #TwoSpace) = 0
    Break
  EndIf
  sTest.s = ReplaceString(sTest, #TwoSpace, #OneSpace)
ForEver
Time2 = ElapsedMilliseconds()

MessageRequester("Done", "Time=" + StrF(Time2 - Time1) + 
                         #TAB$ + StrF((Time2 - Time1)/NumLoops) + "ms/call")
; what a difference a loop makes...
End

Re: Performance anomaly in Win32-Ascii (ReplaceString()?)

Posted: Sat Nov 14, 2015 6:48 am
by Keya
Kenmo,
Thanks for testing! hopefully a few others can give it a run and prove that its my system and not the code itself, but as it's the exact same code running on the exact same system/CPU it's a strange one! its just in an isolated VM like all my other OS, and theres no AV or file system weirdness going on that i know of.

And its only the Ascii version - the exact same Unicode version on the exact same OS runs as normal, which suggests to me that it's probably not something weird with my system, but a problem with the code

Hi Amilcar,
Thankyou! your demo also exhibits the same anomaly on my system, but it's in your 2nd timing set, not the 1st. That is, this one:

Code: Select all

Time1 = ElapsedMilliseconds()
Repeat
  If FindString(sTest, #TwoSpace) = 0
    Break
  EndIf
  sTest.s = ReplaceString(sTest, #TwoSpace, #OneSpace)
ForEver
Time2 = ElapsedMilliseconds()
so the problem is still seemingly with FindString or ReplaceString like my original

;OSX-64-Asc: Time2=207 2.0699999332ms/call
;Lnx-64-Asc: Time2=209 2.0899999142ms/call
;Win-64-Uni: Time2=227 2.2699999809ms/call
;Lnx-64-Uni: Time2=232 2.3199999332ms/call
;Win-64-Asc: Time2=233 2.3299999237ms/call
;Win-32-Uni: Time2=257 2.5699999332ms/call
;OSX-64-Uni: Time2=266 2.6600000858ms/call
;Win-32-Asc: Time2=817 8.1700000763ms/call
I'll try and isolate it further...

Re: Performance anomaly in Win32-Ascii (ReplaceString()?)

Posted: Sat Nov 14, 2015 7:26 am
by Keya
FindString seems fine - it appears to be twice as fast in Ascii mode than Unicode on my Win32 system

ReplaceString() however seems confirmed... can somebody with Win32 please try this to check your Ascii vs Unicode timings with the following code? thanks

Code: Select all

NumLoops.i = 5000
Test.s = Space(8000000) ;8mb
Time1 = ElapsedMilliseconds()
For i = 1 To NumLoops
  Test.s = ReplaceString(Test, "  ", " ")
Next i
Time2 = ElapsedMilliseconds()
Debug("Time=" + StrF((Time2-Time1),3) )
;OSX-64-Uni = Time=83.000
;Win-64-Uni = Time=88.000
;OSX-64-Asc = Time=90.000
;Win-64-Asc = Time=95.000
;Lnx-32-Asc = Time=97.000
;Lnx-32-Uni = Time=101.000
;Win-32-Uni = Time=108.000
;Lnx-64-Uni = Time=147.000
;Lnx-64-Asc = Time=156.000
;Win-32-Asc = Time=486.000

I also did a string test without ReplaceString, both with new strings, same strings, and appending strings:

Code: Select all

NumLoops.i = 200
Test.s = Space(1000000) ;1mb
Time1 = ElapsedMilliseconds()
For i = 1 To NumLoops
  ;sNew.s = Left(Test, 1000000 - i)  ;Test1 - new string
  ;Test.s = Left(Test, 1000000 - i)  ;Test2 - same string
  ;Test = Test + "x"                 ;Test3 - appending
Next i
Time2 = ElapsedMilliseconds()
Debug("Time=" + StrF((Time2-Time1),3) )

;New string:
;Win-32-Asc: Time=237.000
;Win-32-Uni: Time=422.000
;Same string:
;Win-32-Asc: Time=236.000
;Win-32-Uni: Time=415.000
;Appending
;Win-32-Asc: Time=506.000
;Win-32-Uni: Time=1183.000
They all ran fine with Ascii winning every time, so it definitely seems to be a ReplaceString() problem

Re: Performance anomaly in Win32-Ascii (ReplaceString()?)

Posted: Sat Nov 14, 2015 7:49 am
by wilbert
I think the problem might be related to specific Windows versions so when you test, please specify the Windows version you are using.
I'm using Windows 10 and don't see a significant difference.

Re: Performance anomaly in Win32-Ascii (ReplaceString()?)

Posted: Sat Nov 14, 2015 7:55 am
by Keya
WinXP-32, Win7-64, Linux Mint 32 & 64, OSX El Capitan 64, were used for all testings above. All run on exactly the same computer as VMs which is kinda handy for performance comparison i guess. Oh and occasionally Win10-64 with zero network access, lol, but i didnt use that for any of these tests
seems strange if its an XP issue though because the Unicode version is fine, and ReplaceString() is the only function that seems to be showing the anomaly, everything else seems fine :)

Re: Performance anomaly in Win32-Ascii (ReplaceString()?)

Posted: Sat Nov 14, 2015 8:19 am
by GPI
But it is the only diffence. It seems that XP is the reason. Maybe the String-Functions of PureBasic uses some Windows-Api?

btw.: XP is outdated, you should not use it anymore!

Re: Performance anomaly in Win32-Ascii (ReplaceString()?)

Posted: Sat Nov 14, 2015 8:24 am
by Keya
GPI wrote:But it is the only diffence.
not just the OS - the code generated for Ascii vs Unicode is also different, so it might be premature to say one way or the other if its OS or code at fault :)
Hopefully if more people with Win32 and particularly XP can try my last demo, and if they turn up normal results then that can help prove it's a problem with my system or XP specifically

Re: Performance anomaly in Win32-Ascii (ReplaceString()?)

Posted: Sat Nov 14, 2015 8:47 am
by GPI
Here on Win10 64bit os and running a 32bit programm:
unicode: 32444
ascii: 29417


Maybe your xp-installation is corrupt?

Re: Performance anomaly in Win32-Ascii (ReplaceString()?)

Posted: Sat Nov 14, 2015 9:10 am
by Keya
GPI wrote:Maybe your xp-installation is corrupt?
Well, i guess we can never rule that out haha :)
This ReplaceString() thing is the only place the anomaly has reared its head though... i would've thought other functions such as Len, FindString etc, or string concatenation etc might also have a problem, but everything else i've tried so far is fine ... just Win32, just Ascii-compiled, and just ReleaseString()

I just ran the 32bit exes on my Win7-64, and they ran fine there ... 140ms unicode / 175ms ascii

My friend emailed back she also has XP-32 and she got Ascii=1722ms / Unicode=647ms, then Ascii=1498ms / Unicode=682ms. Not quite as dramatic, but both in excess of 2x as slow in Ascii, hmm!

Re: Performance anomaly in Win32-Ascii (ReplaceString()?)

Posted: Sat Nov 14, 2015 9:16 am
by wilbert
Keya wrote:This ReplaceString() thing is the only place the anomaly has reared its head though
You could create a test with in-place replacing and see if it happens also in that case.

Re: Performance anomaly in Win32-Ascii (ReplaceString()?)

Posted: Sat Nov 14, 2015 9:53 am
by TroaX
I tested the Code on my System:
Win 10 x86 Unicode: 37583
Win 10 x86 ASCII: 35699
Win 10 x64 Unicode: 35744
Win 10 x64 ASCII: 31245

I can't confirm this Effect.

Re: Performance anomaly in Win32-Ascii (ReplaceString()?)

Posted: Mon Nov 16, 2015 4:34 pm
by Fred
Performances can vary, it's hardly a bug.