Godot-proposals: Add an `extend()` method in Array

Created on 24 Oct 2020  ·  6Comments  ·  Source: godotengine/godot-proposals

Describe the project you are working on:
gdscript plugins

Describe the problem or limitation you are having in your project:
it seems

for i in b.size():
  a.append(b[i])

is faster than

a+=b

(especially if you are working with large arrays), but noisier (less laconic, this is most noticeable when you have to repeat it often in the code).

Describe the feature / enhancement and how it helps to overcome the problem or limitation:
I think the built-in extend() method would be faster than for .. append() gdscript loop and certainly faster than a+=b and still look good.

Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:

var a = [1,2]
var b = [3,4]
a.extend(b)

-->
[1,2,3,4]

If this enhancement will not be used often, can it be worked around with a few lines of script?:

for i in b.size():
  a.append(b[i])

or push_back() (it seems marginally faster than append())
also a.resize() can be used

Is there a reason why this should be core and not an add-on in the asset library?:
this is a new Array method

core

Most helpful comment

I don't necessarily disagree with the addition of extend(), so let's say your proposal actually hides an issue with += being unnecessarily slower when the operand is an array due to the loose translation, and that should be fixed.
I think there was another related issue with it but I can't find it.

About the name, it seems append_array would make it more consistent with other array types:
image

All 6 comments

These already work:

    var a = [1, 2]
    var b = [3, 4]
    var c = a + b
    print(c)

and

    var a = [1, 2]
    var b = [3, 4]
    a += b
    print(a)

Both print:

[1, 2, 3, 4]

If the reason of your proposal is the slowness of the += operator, I think the proposal should be to optimize them, not have another function that somehow does the same thing faster. I'm actually very surprised that it would be slower than a for loop manually written in GDScript.

I suspect it's because GDScript loosely translates a += b as a a = a + b operation which allocates an intermediary array. The whole point of having += is not just being shorter to write, it's an opportunity for the interpreter to do a more informed operation.

I thought this is not efficient mainly because the new array is being created.
especially the difference in speed is felt on large arrays.

and also I think this method would be convenient for beginners who switched from other languages ​​where there is extend() for example from Python

I don't necessarily disagree with the addition of extend(), so let's say your proposal actually hides an issue with += being unnecessarily slower when the operand is an array due to the loose translation, and that should be fixed.
I think there was another related issue with it but I can't find it.

About the name, it seems append_array would make it more consistent with other array types:
image

I think, this would be a nice addition. I just ran into this a few minutes ago:

func test():
    var arr := []

    append_one(arr)
    print(arr)
    # Prints "[1]"

    append_some(arr)
    print(arr)
    # Prints "[1]"

func append_one(arr : Array):
    arr.append(1)

func append_some(arr : Array):
    arr += [2, 3]

Took me a while to realize, that += creates a new, local array in the "append_some" function. But well, thinking about that, the behavior makes sense.

Having something like extend() or append_array() would be nice to have in such situations.

Was this page helpful?
0 / 5 - 0 ratings