Discussion:
Which is better
(too old to reply)
StanWeiss
2024-05-30 14:58:45 UTC
Permalink
I have always used ()^.5 is SQRT() better for any reason?

Thanks
Stan
--
This email has been checked for viruses by Avast antivirus software.
www.avast.com
ObiWan
2024-05-30 15:33:53 UTC
Permalink
:: On Thu, 30 May 2024 10:58:45 -0400
:: (microsoft.public.vb.general.discussion)
Post by StanWeiss
I have always used ()^.5 is SQRT() better for any reason?
It would be interesting to check the speed and the precision of both
methods, it shouldn't be difficult putting together a couple of loops
doing each operation on a given list of values and filling two arrays,
at end it will be possible to check the elapsed time for each loop and
to compare the results to check if there are discrepancies :)
StanWeiss
2024-05-31 13:07:42 UTC
Permalink
Post by ObiWan
:: On Thu, 30 May 2024 10:58:45 -0400
:: (microsoft.public.vb.general.discussion)
Post by StanWeiss
I have always used ()^.5 is SQRT() better for any reason?
It would be interesting to check the speed and the precision of both
methods, it shouldn't be difficult putting together a couple of loops
doing each operation on a given list of values and filling two arrays,
at end it will be possible to check the elapsed time for each loop and
to compare the results to check if there are discrepancies :)
Thanks.
Before I look at speed I wanted to make sure that they didn't produce a
different results.

I ran the following code.

For a = .12345 To 10000 Step .12345
   If (a)^.5 <> SQR(a) Then
      WorkString = WorkString & "Calculation Mismatch " & Format(a,
"0.0######################") & " - " & Format((a)^.5,
"0.0######################") & " - " & Format(SQR(a),
"0.0######################") & VBCrLf
   End If
Next

I got he following results. I don't see the difference

Calculation Mismatch 97.4020500000008 - 9.86924769169367 - 9.86924769169367
Calculation Mismatch 396.644849999983 - 19.9159446173156 - 19.9159446173156
Calculation Mismatch 1272.64605000027 - 35.6741650217671 - 35.6741650217671
Calculation Mismatch 1485.84420000035 - 38.5466496598648 - 38.5466496598648
Calculation Mismatch 1623.49095000041 - 40.2925669323811 - 40.2925669323811
Calculation Mismatch 1624.60200000041 - 40.3063518567534 - 40.3063518567534
Calculation Mismatch 1889.89605000051 - 43.4729346835535 - 43.4729346835535
Calculation Mismatch 1935.44910000053 - 43.9937393273239 - 43.9937393273239
Calculation Mismatch 1964.33640000054 - 44.3208348296886 - 44.3208348296886
Calculation Mismatch 1984.33530000055 - 44.5458785972456 - 44.5458785972456
Calculation Mismatch 2192.59545000063 - 46.8251583019281 - 46.8251583019281
Calculation Mismatch 2252.83905000065 - 47.4640816828963 - 47.4640816828963
Calculation Mismatch 2274.44280000066 - 47.6911186700486 - 47.6911186700486
Calculation Mismatch 2798.73495000086 - 52.9030712719107 - 52.9030712719107
Calculation Mismatch 2799.84600000086 - 52.9135710380698 - 52.9135710380699
Calculation Mismatch 3036.37620000096 - 55.103322948811 - 55.103322948811
Calculation Mismatch 3118.10010000099 - 55.8399507521361 - 55.8399507521361
Calculation Mismatch 3566.84085000116 - 59.7230345009458 - 59.7230345009458
Calculation Mismatch 3648.68820000119 - 60.4043723583086 - 60.4043723583086
Calculation Mismatch 3709.91940000122 - 60.9091076933591 - 60.9091076933591
Calculation Mismatch 3947.93100000131 - 62.8325632136817 - 62.8325632136817
Calculation Mismatch 4299.51660000145 - 65.5706992489896 - 65.5706992489896
Calculation Mismatch 5346.74295000186 - 73.1214260665221 - 73.1214260665221
Calculation Mismatch 5400.81405000188 - 73.4902309834571 - 73.4902309834571
Calculation Mismatch 5441.92290000189 - 73.769389993424 - 73.7693899934241
Calculation Mismatch 5945.59890000209 - 77.1077097312719 - 77.1077097312719
Calculation Mismatch 6015.34815000212 - 77.5586755302211 - 77.5586755302211
Calculation Mismatch 6171.88275000218 - 78.5613311369033 - 78.5613311369033
Calculation Mismatch 6491.4948000023 - 80.5698132057057 - 80.5698132057056
Calculation Mismatch 6532.60365000232 - 80.8245238154999 - 80.8245238154999
Calculation Mismatch 6802.34190000242 - 82.4763111444882 - 82.4763111444882
Calculation Mismatch 6898.87980000246 - 83.0594955438718 - 83.0594955438718
Calculation Mismatch 6902.95365000246 - 83.0840156107206 - 83.0840156107206
Calculation Mismatch 7217.25735000258 - 84.9544427914314 - 84.9544427914313
Calculation Mismatch 7280.09340000261 - 85.3234633615081 - 85.323463361508
Calculation Mismatch 7443.54120000267 - 86.2759595716134 - 86.2759595716134
Calculation Mismatch 7910.55255000285 - 88.9412870943683 - 88.9412870943683
Calculation Mismatch 8340.52890000193 - 91.3264961552885 - 91.3264961552885
Calculation Mismatch 8760.50579999899 - 93.5975736864957 - 93.5975736864957

Thanks,
Stan
--
This email has been checked for viruses by Avast antivirus software.
www.avast.com
StanWeiss
2024-06-01 19:56:12 UTC
Permalink
Post by StanWeiss
I have always used ()^.5 is SQRT() better for any reason?
Thanks
Stan
If anyone is reading this thread. Can they please double check the
results I got. I am shocked at how much faster Square Root is.

Power Start June 1 2024 15:48:57
Power End June 1 2024 15:50:50
Square Root Start June 1 2024 15:50:50
Square Root End June 1 2024 15:51:3

Thanks,
Stan
--
This email has been checked for viruses by Avast antivirus software.
www.avast.com
ObiWan
2024-06-03 07:34:06 UTC
Permalink
:: On Sat, 1 Jun 2024 15:56:12 -0400
:: (microsoft.public.vb.general.discussion)
Post by StanWeiss
If anyone is reading this thread. Can they please double check the
results I got. I am shocked at how much faster Square Root is.
Use the "datediff" to obtain a difference in seconds

https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/datediff-function

that will show it better, also, it's no surprise that sqr() is faster,
it's optimized for that, while using "math" means running a bunch of
floating point calcs under the hood
ObiWan
2024-06-03 07:37:25 UTC
Permalink
Post by ObiWan
Use the "datediff" to obtain a difference in seconds
https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/datediff-function
air code

dtStr = Now()

do some stuff...

dtEnd = Now()

dDiff = datediff("s", dtStr, dtEnd)

dDiff will contain the elapsed time in seconds, there's a way to use
milliseconds, but needs some API calls, the above is simpler and is
usually fine for "long" timings
ObiWan
2024-06-03 12:35:46 UTC
Permalink
:: On Mon, 3 Jun 2024 09:37:25 +0200
:: (microsoft.public.vb.general.discussion)
Post by ObiWan
Post by ObiWan
Use the "datediff" to obtain a difference in seconds
https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/datediff-function
air code
dtStr = Now()
do some stuff...
dtEnd = Now()
dDiff = datediff("s", dtStr, dtEnd)
Or either (air code)

Function ElapsedTime(ByVal dt As Date, Optional ByVal bStr As Boolean = False) As Double
Static dtStr As Date

If bStr Then
dtStr = Now()
ElapsedTime = dtStr
Exit Function
End If
ElapsedTime = DateDiff("s", dtStr, Now())
End Function


the way it works should hopefully be clear :)
ObiWan
2024-06-03 12:59:07 UTC
Permalink
:: On Mon, 3 Jun 2024 14:35:46 +0200
:: (microsoft.public.vb.general.discussion)
Post by ObiWan
the way it works should hopefully be clear :)
fixed the code (the previous ... bah :P)

Function ElapsedTime(Optional ByVal bStr As Boolean = False) As Double
Static dtStr As Date

If bStr Then
dtStr = Now()
ElapsedTime = 0
Exit Function
End If
ElapsedTime = DateDiff("s", dtStr, Now())
End Function

anyway, the call is

Call ElapsedTime(True)

... do some job ...

TimeTaken = ElapsedTime(False)

where "TimeTaken" will be the time taked to "do some job" expressed in
seconds
StanWeiss
2024-06-03 14:24:52 UTC
Permalink
Post by ObiWan
:: On Mon, 3 Jun 2024 14:35:46 +0200
:: (microsoft.public.vb.general.discussion)
Post by ObiWan
the way it works should hopefully be clear :)
fixed the code (the previous ... bah :P)
Function ElapsedTime(Optional ByVal bStr As Boolean = False) As Double
Static dtStr As Date
If bStr Then
dtStr = Now()
ElapsedTime = 0
Exit Function
End If
ElapsedTime = DateDiff("s", dtStr, Now())
End Function
anyway, the call is
Call ElapsedTime(True)
... do some job ...
TimeTaken = ElapsedTime(False)
where "TimeTaken" will be the time taked to "do some job" expressed in
seconds
Thanks. Yes this is much easier to read the difference.

Power 114
Square Root 14

Stan
--
This email has been checked for viruses by Avast antivirus software.
www.avast.com
ObiWan
2024-06-03 15:25:43 UTC
Permalink
:: On Mon, 3 Jun 2024 10:24:52 -0400
:: (microsoft.public.vb.general.discussion)
Post by StanWeiss
Thanks. Yes this is much easier to read the difference.
Y/W
Post by StanWeiss
Power 114
Square Root 14
As I wrote, the difference is that the SQR() function invokes the CPU
native function(s) to perform the calculation, while using the "power"
approach, VB is forced to "do the math" using its own math libraries
ObiWan
2024-06-03 15:39:17 UTC
Permalink
:: On Mon, 3 Jun 2024 17:25:43 +0200
:: (microsoft.public.vb.general.discussion)
Post by ObiWan
As I wrote, the difference is that the SQR() function invokes the CPU
native function(s) to perform the calculation, while using the "power"
approach, VB is forced to "do the math" using its own math libraries
in short, the optimizer isn't "smart" enough to understand that (x)^0.5
may be converted to an sqr() call under the hood, so VB doea all the
math ...

It would be interesting, if you used the "^0.5" approach in some real
app code, to replace those with "sqr()" and check the resulting speed
ObiWan
2024-06-04 16:16:32 UTC
Permalink
:: On Mon, 3 Jun 2024 17:39:17 +0200
:: (microsoft.public.vb.general.discussion)
Post by ObiWan
It would be interesting, if you used the "^0.5" approach in some real
app code, to replace those with "sqr()" and check the resulting speed
Note: check last post here

https://www.vbforums.com/showthread.php?430544-How-Long-My-Program-Is-On&highlight=timegetTime

the "timeGetTime" API returns the time in milliseconds ;-)
ObiWan
2024-06-05 14:00:51 UTC
Permalink
Post by ObiWan
the "timeGetTime" API returns the time in milliseconds ;-)
Otherwise you may try the following code


Option Explicit

Private Declare Function QueryPerformanceFrequency Lib "kernel32" _
(lpFrequency As Currency) As Long

Private Declare Function QueryPerformanceCounter Lib "kernel32" _
(lpPerformanceCount As Currency) As Long

' calculates elapsed time
Function TimeCalc(Optional ByVal bStr As Boolean = False) As Single
Static cFreq As Currency
Static cStart As Currency
Dim cEnd As Currency
Dim fElapsed As Single
Dim lRet As Long

If bStr Then
' initialize and get current time value
lRet = QueryPerformanceFrequency(cFreq)
If lRet <> 0 Then
lRet = QueryPerformanceCounter(cStart)
Else
' performance counters not supported
TimeCalc = -1
End If
Exit Function
End If

' obtain current time and calculate elapsed time
lRet = QueryPerformanceCounter(cEnd)
fElapsed = ((cEnd - cStart)*1000/cFreq)

' return elapsed time
TimeCalc = fElapsed
End Sub

you start by calling "TimeCalc" once at startup to check if the query
performance counters are suppported

fRet = TimeCalc()
If fRet = -1 Then
' not supported !!
End If

if so you then proceed with something like

Call TimeCalc()

... do the job ...

fElapsedTime = TimeCalc(False)

and then the "fElapsedTime" will give you the elapsed time, not that
one usually needs such a granularity, but then one may never know :)
ObiWan
2024-06-05 14:39:51 UTC
Permalink
:: On Wed, 5 Jun 2024 16:00:51 +0200
:: (microsoft.public.vb.general.discussion)
fRet = TimeCalc(True)
If fRet = -1 Then
' not supported !!
End If
Call TimeCalc(True)
... do the job ...
fElapsedTime = TimeCalc()
corrected

Loading...