tarretarretarre

Passing byref vs just using a Local\Global value or both?

13 posts in this topic

Lets say you have this code, imagine its a laaarge project.
 

local $myArr[1]; This array

while 1
    myFunc($myArr)
    myFunc2()
wend



func myFunc(byref $arr)
    ;Heavy modifying to $arr passed by refrence including com objects and large data
endfunc

func myFunc2()
    ;Heavy modifying to $myArr from global scope including objects and large data
endfunc

I know both ways work, but i wonder if one way is more efficient than the other? is it just a principle of not mixing up local\global values? or does it affect the speed anything at all? 

Regards

Share this post


Link to post
Share on other sites



myFunc: It's going to actually use $myArr but use it with the name $arr to access it

myFunc2: It's going to actually use $myArr and use the name $myArr to access it

Understand that when you use reference it's going to copy the variable. Reference variables are going to be references to the original variable, you're still working with the original variable, it's just a different name. One reason to pass the variable by Reference instead of just accessing the global variable is for readability and make the function less specific. What I mean by that is if you have your own custom Find function for 2d arrays, you're trying to find a 2d array inside a 2d array. Instead of using the global 2d array that you know is valid in your script, you pass it to the function anyway.

Share this post


Link to post
Share on other sites
5 minutes ago, JohnOne said:

Directly accessing the array  (myFunc2) is more efficient.

Depends on how you define efficient. Passing a large array means that the array has to be copied to another array in the function, which means time taken for the copy process and memory taken by the copied array. ByRef doesn't have either of those penalties, there's no copy so less memory used in the function, and less time taken to copy the array to another array.

Normally you wouldn't be passing a global array/variable using ByRef unless you do it to avoid the 2 things I mentioned. Otherwise, all you're doing is using a local variable to change the global variable, which it being Global you don't need to do. You would usually only do this if you're using the function more than once in more than one script.

You would pass something ByRef if you're calling one function from another function and want to pass information from a local variable in the first function to the second function which otherwise wouldn't be able to access it.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

I had to test it because my thought process for reference was it's the same as accessing the variable under a different name, so there should be no performance difference. Though I got that from C++ so it could be different for autoit. So my test, using an array with 16,777,216 elements, had it call a ByRef function and a function with Global access 1,000,000 times, and the function did some random access on the elements in the array.

My results:

Quote

Test 1:
ByRef = 4.59156988441382
Global = 4.92228892580408

Test 2
ByRef = 4.56436635400864
Global = 4.83667461824611

Test 3
ByRef = 4.59719754870342
Global = 4.97156799861628

Test 4
ByRef = 4.58162080094746
Global = 4.8747494111387

Test 5
ByRef = 4.56079234726541
Global = 4.89647722208809

Average:

Quote

ByRef = 4.57910938706775

Global = 4.900351635178652

Median:

Quote

ByRef = 4.58162080094746

Global = 4.89647722208809

The Script:

Global $aTest[16777216]
Global $iDiffRef = 0
Global $iDiffGlobal = 0
Global $tTimer

$tTimer = TimerInit()

For $i = 0 to 1000000
    Test1($aTest)
Next

$iDiffRef = TimerDiff($tTimer) / 1000

$tTimer = TimerInit()

For $i = 0 to 1000000
    Test2()
Next

$iDiffGlobal = TimerDiff($tTimer) / 1000

MsgBox("", "", "ByRef = " & $iDiffRef & @CRLF & "Global = " & $iDiffGlobal)

Func Test1(ByRef $aArray)
    $aArray[Random(0, UBound($aArray) - 1)] = Random(0, 255, 1)
EndFunc

Func Test2()
    $aTest[Random(0, UBound($aTest) - 1)] = Random(0, 255, 1)
EndFunc

My conclusion? The difference in time is so minuscule that performance is not an issue

Edited by InunoTaishou
1 person likes this

Share this post


Link to post
Share on other sites

And before someone comes in and says that the test is invalid because the ByRef func is called first, here's the results with the for loops switched

Quote

Test 1:
ByRef = 4.58433869164087
Global = 4.88279197731277

Test 2:
ByRef = 4.5442805081804
Global = 4.76154360336273

Test 3:
ByRef = 4.56068124135926
Global = 4.75320585582177

Test 4:
ByRef = 4.56418107740298
Global = 4.74793793443911

Test 5:
ByRef = 4.68860497826528
Global = 4.82882573669221

 

Share this post


Link to post
Share on other sites
5 hours ago, InunoTaishou said:

Understand that when you use reference it's going to copy the variable.

Wrong.


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

#9 ·  Posted (edited)

And  a different script which I think just measures access time without function call.

Local $myArr[1000001]; This array

Sleep(500)

$timer = TimerInit()

myFunc($myArr)
ConsoleWrite("ByRef " & TimerDiff($timer) & @CRLF)

$timer = TimerInit()

myFunc2()
ConsoleWrite("Global " & TimerDiff($timer) & @CRLF)

Func myFunc(ByRef $arr)
    For $i = 0 To 1000000
        $arr[$i] = $i
    Next
EndFunc   ;==>myFunc

Func myFunc2()
    For $i = 0 To 1000000
        $myArr[$i] = $i
    Next
EndFunc   ;==>myFunc2
Quote

ByRef 1656.42429383469

Global 1212.84029968972

ByRef 1680.32492503454
Global 1223.41630521866

ByRef 1655.73951649829
Global 1212.53097236117

 

Edited by JohnOne

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites
8 hours ago, jchd said:

Wrong.

Ya, I explained myself properly in everything else though.

Share this post


Link to post
Share on other sites

I know, I was simply pointing this out for future noob readers.

1 person likes this

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

I make some test with ByRef but with other kind of data.

This test compares speed of passing large amount of binary data INSIDE <> OUTSIDE function.

 

#Tidy_Parameters=/sort_funcs /reel
#include <FileConstants.au3>
#include <MsgBoxConstants.au3>

_Example()
Exit

Func _Example()
    Local $sPDF_FileFullPath = FileOpenDialog("Choose PDF File", "", "PDF files (*.pdf)")
    If @error then Return SetError(@error, @extended, '')

    ConsoleWrite($sPDF_FileFullPath & @CRLF)
    ConsoleWrite('Size = '& FileGetSize($sPDF_FileFullPath) & ' Bytes' & @CRLF)

    Local $hFile = FileOpen($sPDF_FileFullPath,  $FO_BINARY )
    Local $vPDF_Content = FileRead($hFile)
    FileClose($hFile)

    Local $hTimer = 0, $fDiff = 0
    Local $vResult_2a, $vResult_2c
    Local $fDiff_1 = 0, $fDiff_2a = 0, $fDiff_2b = 0, $fDiff_2c = 0, $fDiff_3 = 0

    For $i = 1 To 100
        $hTimer = TimerInit()
        Test1($vPDF_Content)
        $fDiff_1 += TimerDiff($hTimer)

        $hTimer = TimerInit()
        $vResult_2a = Test2($vPDF_Content)
        $fDiff_2a += TimerDiff($hTimer)

        $hTimer = TimerInit()
        Test2($vPDF_Content)
        $fDiff_2b += TimerDiff($hTimer)

        $hTimer = TimerInit()
        $vResult_2c = Test2($vPDF_Content)
        $fDiff_2c += TimerDiff($hTimer)

        $hTimer = TimerInit()
        Test3($vPDF_Content)
        $fDiff_3 += TimerDiff($hTimer)
    Next

    ConsoleWrite("Time 1  : " & $fDiff_1 & @CRLF)
    ConsoleWrite("Time 2a : " & $fDiff_2a & @CRLF)
    ConsoleWrite("Time 2b : " & $fDiff_2b & @CRLF)
    ConsoleWrite("Time 2c : " & $fDiff_2c & @CRLF)
    ConsoleWrite("Time 3  : " & $fDiff_3 & @CRLF)

EndFunc   ;==>_Example

Func Test1(ByRef $vPDF_Content)
EndFunc   ;==>Test1

Func Test2($vPDF_Content)
    Return $vPDF_Content
EndFunc   ;==>Test2

Func Test3($vPDF_Content)
;~  Return $vPDF_Content
EndFunc   ;==>Test3
Quote

Z:\TOOLs\Macro\FORUM\___FORUM -- na forum\QuickPDF\_Viewer\1111_2.pdf
Size = 9036 Bytes
Time 1  : 0.58320639693292
Time 2a : 1.82712798261157
Time 2b : 1.49440731531758
Time 2c : 1.69101498235494
Time 3  : 0.88426188708387
 

 

Quote

Z:\TOOLs\Macro\FORUM\___FORUM -- na forum\QuickPDF\_Viewer\1112.pdf
Size = 782936 Bytes
Time 1  : 1.67352824273863
Time 2a : 523.318094663756
Time 2b : 424.317627247932
Time 2c : 536.550830407455
Time 3  : 179.925790057985
 

 

Quote

Z:\TOOLs\Macro\FORUM\___FORUM -- na forum\QuickPDF\_Viewer\Debenu Cross Platform PDF Library 12.11 Reference Guide.pdf
Size = 2787483 Bytes
Time 1  : 2.09226476436146
Time 2a : 1847.2679805037
Time 2b : 1482.0517522422
Time 2c : 1894.07761938363
Time 3  : 594.040141047097
 

 


Signature beginning:   Wondering who uses AutoIT and what it can be used for ?
* GHAPI UDF - modest begining - comunication with GitHub REST API *
ADO.au3 UDF     POP3.au3 UDF     XML.au3 UDF    How to use IE.au3  UDF with  AutoIt v3.3.14.x  for other useful stuff click the following button

Spoiler

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

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST API *

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 - BETA * ADO.au3 UDF SMTP Mailer UDF *

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Best coding practices * 

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * 

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2017-06-04

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