jasty Posted December 4, 2018 Posted December 4, 2018 (edited) In every other language doing dim $a[3] = [1, 2, 3] $b = $a creates a reference to a but in autoit it always makes a copy. I didn't realize this until I have performance problems and now I'm trying to switch over to the reference behavior. How can I change the above statement so b is a reference to a and not a full copy? Edited December 4, 2018 by jasty
Moderators Melba23 Posted December 4, 2018 Moderators Posted December 4, 2018 jasty, If you are looking to pass the array as a parameter to a function, AutoIt does not make a copy of the array unless you alter the array in some fashion - even then you should be able to use ByRef to prevent this. Can you explain in more detail just what you are trying to do? M23 pixelsearch 1 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area
pixelsearch Posted December 4, 2018 Posted December 4, 2018 (edited) The help file (topic Func) should really be written as Melba23 just explained : MB23 : " If you are looking to pass the array as a parameter to a function, AutoIt does not make a copy of the array unless ..." Help file : "Arrays should be passed to user-defined functions using the ByRef keyword to avoid the overhead of copying all the data in the array." * When you read this sentence in the help file, your 1st impression is that, without the ByRef keyword, the Array will be copied in the Function. The next sentences in the help file indicate you that it it's not always the case. * When you read MB23 here, you understand immediately that, without the ByRef keyword, the Array will not be copied in the Function, unless... I prefer MB23's explanation Edited December 4, 2018 by pixelsearch "I think you are searching a bug where there is no bug... don't listen to bad advice."
Moderators Melba23 Posted December 4, 2018 Moderators Posted December 4, 2018 pixelsearch, I believe the Help file text should remain as it currently reads - there is no guarantee that future AutoIt releases will retain the "no copy unless altered" functionality and so the user is best advised to pass arrays ByRef in all cases, as the Help file recommends (for precisely this reason). M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area
pixelsearch Posted December 4, 2018 Posted December 4, 2018 (edited) Good to know, thx MB23 In fact, I was a bit perplexed about this "no copy unless altered" because it seems to be a functionality added to help the programmer, in case he forgot to use the ByRef keyword, to avoid a copy of the Array to be automatically done : this is how AutoIt reacts right now, to "avoid copying all the data [Array in our case], which would impose a significant performance penalty" If this functionality disappears in future AutoIt releases, programmers will have to be more careful : forgetting the ByRef Keyword will automatically do a copy of the Array (if I understood you well) Edited December 4, 2018 by pixelsearch "I think you are searching a bug where there is no bug... don't listen to bad advice."
jasty Posted December 4, 2018 Author Posted December 4, 2018 Oh so the array copy stuff only happens if the array is altered? Is that always the case? In the above code is $a actually copied?
pixelsearch Posted December 4, 2018 Posted December 4, 2018 23 minutes ago, jasty said: In the above code is $a actually copied? Hi jasty It sure is, as stated in the help file (topic Global/Local) : "A unique feature in AutoIt is the ability to copy arrays like this: $mycopy = $myarray In this case $mycopy will be an exact copy of $myarray and will have the same dimensions" As Melba23 wrote, the only case where it won't be copied is if you use the Array as a parameter in a function, using the keyword ByRef . Then the Array in the function won't be a copy of the original one. In case it's not your need, please indicate why you need an array refering to another one, outside a function ? Maybe It would help readers to provide a solution "I think you are searching a bug where there is no bug... don't listen to bad advice."
jasty Posted December 4, 2018 Author Posted December 4, 2018 What about something like this... does the array get copied after I retrieve it? Func MyFunc($val, $arraytype) if $arraytype == 0 then $array = RetrieveDataOfSomeKind() else $array = RetrieveDataOfSomeOtherKind() endif $result = DoSomeAction($val, $array) Return $result EndFunc After coming from other languages I've never considered the assignment operator to be expensive.
pixelsearch Posted December 5, 2018 Posted December 5, 2018 (edited) @jasty Yes, the retrieved elements of the array are copied into $array Here is a script that could match partially your function (at least, this is how I understood it) #include <Array.au3> #include <MsgBoxConstants.au3> Global $aBig_array[10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] _ArrayDisplay($aBig_array, "$aBig_array - in main") Test() Func Test() $array = RetrieveDataOfSomeKind() ; an Array should be returned to populate $array _ArrayDisplay($array, "$array - in test()") If @error = 1 Then MsgBox($MB_TOPMOST, "Error", "$array is not an array") EndIf EndFunc Func RetrieveDataOfSomeKind() Local $aSmall_array[2] $aSmall_array[0] = $aBig_array[2] $aSmall_array[1] = $aBig_array[4] Return $aSmall_array EndFunc What Melba23 did explain concerned the ByRef keyword, for instance : #include <Array.au3> Global $aBig_array[10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] _ArrayDisplay($aBig_array, "In main - before test()") Test($aBig_array) _ArrayDisplay($aBig_array, "In main - after test()") Func Test(ByRef $array) ; $aBig_array[] hasn't been copied in the function, because of ByRef keyword ; and it will never be copied, even if you alter an element of $array. ; ; Now, notice how altering an element of $array will modify the original $aBig_array $array[9] = 999999999 _ArrayDisplay($array, "$array - In test") EndFunc Same without ByRef (use it only if you really need a copy of the whole array in the function) #include <Array.au3> Global $aBig_array[10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] _ArrayDisplay($aBig_array, "In main - before test()") Test($aBig_array) _ArrayDisplay($aBig_array, "In main - after test()") Func Test($array) ; $aBig_array[] hasn't been copied in the function, BUT : ; it will be copied, as soon as you alter any element of $array ! ; This functionality may eventually be removed in next AutoIt releases, ; so scripters will have to be extra careful concerning the ByRef keyword. ; The only case ByRef shouldn't be used is if you *really* need a copy of the array, here. ; ; Now, notice how altering an element of $array will NOT modify the original ($aBig_array) $array[9] = 999999999 _ArrayDisplay($array, "$array - In test") EndFunc One more thing : Const ByRef (or ByRef Const) is even better, in case you don't want at all to modify the original array. It's an extra protection for scripters : an error will be generated if you modify any element inadvertly during the function : Global $aBig_array[10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Test($aBig_array) Func Test(ByRef Const $array) ; Notice how altering inadvertly an element of $array will generate an error : thanks Const ! $array[9] = 999999999 EndFunc ; Console shows the error : ; " Cannot assign values to constants " ; $array[9] = 999999999 ; ^ ERROR Good luck Edited December 5, 2018 by pixelsearch wolflake 1 "I think you are searching a bug where there is no bug... don't listen to bad advice."
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now