You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Extra clones
Calling set and many other methods of Array with Variant arguments clones the Variant.
Example:
let arr = Array::new();
arr.set(0,Variant::nil());
The set will call internally:
pubfnset(&mutself,index:usize,value:T){let ptr_mut = self.ptr_mut(index);// SAFETY: `ptr_mut` just checked that the index is not out of bounds.unsafe{
value.to_variant().move_into_var_ptr(ptr_mut);}}
which will do to_variant(), even though the argument is already variant. There are multiple such cases throughout the Array class.
Takes ownership of VariantArray. It might seem small thing, but for my use cases, i make about 10000 or more calls using callv. Allocating the array every time takes about 100-150ms of a 4s timeslice. I would like to be able to reuse the array. Eg. send it to the callv method, and after the method is called be able to reuse my array:
which will do to_variant(), even though the argument is already variant. There are multiple such cases throughout the Array class.
The argument is not Variant, it is T. Just your specific monomorphization uses T = Variant. Unfortunately we don't have specialization in Rust, so optimizing for individual T's is hard (not impossible, but very annoying).
However, there are possible alternatives:
value: &T parameter -- since to_variant(&self) also takes a reference, we don't need a value here. However, in your example of passing a newly constructed variant, this would still involve a clone.
a new ToGodot::into_variant() method which takes values and is a no-op for Self = Variant.
Calling callv [...] Takes ownership of VariantArray. It might seem small thing, but for my use cases, i make about 10000 or more calls using callv. Allocating the array every time takes about 100-150ms of a 4s timeslice. I would like to be able to reuse the array. Eg. send it to the callv method, and after the method is called be able to reuse my array:
Yes, this is definitely planned. There are thousands of generated APIs that currently take value where they don't have to, also for Gd<T>.
2. a new `ToGodot::into_variant()` method which takes values and is a no-op for `Self = Variant`.
I've started working on this btw, this does require changing things in several places to make sure it's used everywhere it's appropriate.
To make this work for Array in particular, we do need to optimize the constructors that take owned values. For instance FromIterator. Since currently From<&[T]> is our fastest implementation since it can just use pointers to write all the values to the array, but it can't use into_variant since it's borrowed. Maybe just a From<Vec<T>> could work for now though, optimizing FromIterator is harder since we'd need to rely on size_hint.
From Performance Investigation
Calling set and many other methods of
Array
withVariant
arguments clones theVariant
.Example:
The set will call internally:
which will do
to_variant()
, even though the argument is already variant. There are multiple such cases throughout theArray
class.Calling
callv
:Takes ownership of VariantArray. It might seem small thing, but for my use cases, i make about 10000 or more calls using callv. Allocating the array every time takes about 100-150ms of a 4s timeslice. I would like to be able to reuse the array. Eg. send it to the callv method, and after the method is called be able to reuse my array:
The text was updated successfully, but these errors were encountered: