Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uses StringName in GDExtension perf critical instance creation & method/properties setter/getter #67750

Merged

Conversation

touilleMan
Copy link
Member

@touilleMan touilleMan commented Oct 22, 2022

Godot-CPP twin PR: godotengine/godot-cpp#896

Function such as gdnative_classdb_construct_object would obsviously benefit from using StringName instead of char * (it's the whole point of StringName after all !)

Functions such as gdnative_variant_get_ptr_builtin_method also benefit in case it is called as part of the actual function call (e.g. in dynamic language or if the output of gdnative_variant_get_ptr_builtin_method is not cached)

On the other hand, I've kept use of char * in classdb_register_extension_*, GDNativeExtensionClassGetVirtual functions and GDNativePropertyInfo/GDNativeMethodInfo/GDNativeExtensionClassMethodInfo structures.

The reason is those are not performance critical:

  • classdb_register_extension_* are called once when the extension is initialized
  • GDNativeExtensionClassMethodInfo is only used by classdb_register_extension_*
  • GDNativeExtensionClassGetVirtual is cached by classDB
  • GDNativePropertyInfo/GDNativeMethodInfo are only used by ClassDB::get_method_list/ClassDB::get_property_list which are called by stuff like editor a gdscript analyzer, so I guess this is not used at release. However we may want to convert it anyway to speed up gdscript analyzer (though I don't know this code at all so it's very possible this would bring no real performance).

I can update the PR if you think it would be better for consistency to use StringName everywhere.

@neikeq
Copy link
Contributor

neikeq commented Oct 22, 2022

I've said this in the past. I think all these methods should receive StringName. IIRC, the char * conversion (StringName(const char *)) copy ctor) doesn't support Unicode. Of course, the conversion could be fixed, but it's easier to just receive the StringName.

@touilleMan
Copy link
Member Author

@neikeq good point, I'm convertion everything to StringName then ;-)

@Chaosus Chaosus added this to the 4.0 milestone Oct 23, 2022
@touilleMan touilleMan force-pushed the stringname-in-gdextension-api branch from 50624cd to a4af43e Compare October 23, 2022 09:39
@touilleMan touilleMan requested review from a team as code owners October 23, 2022 09:39
@touilleMan touilleMan force-pushed the stringname-in-gdextension-api branch 2 times, most recently from 0755c32 to 9871bac Compare October 23, 2022 10:41
@touilleMan
Copy link
Member Author

@neikeq I've updated the PR, now what we have:

GDExtension C API uses StringName instead of const char * (some places uses String depending on what is used by ClassDB, e.g. hint_string)

GDNativeExtensionClassMethodInfo has been simplified by removing the get_argument_type_func/get_argument_info_func/get_argument_metadata_func.
The main reason for that is simplifies the memory management of the String/StringName objects: GDNativeMethodInfo/GDNativePropertyInfo/GDNativeExtensionClassMethodInfo are now only used as argument to to the lassdb_register_extension_* method or for the get_property_list_func/free_property_list_func.

  • for lassdb_register_extension_* the GDExtension user know he can free the resources once the function has return
  • for get_property_list_func/free_property_list_func, the free_property_list_func is the obvious place to do the resource cleanup

On top of that, this simplifies the implemention for GDExtension user (it's much simpler to pass an array of GDNativePropertyInfo that to pass a function pointer that should construct a GDNativePropertyInfo !).

@touilleMan touilleMan force-pushed the stringname-in-gdextension-api branch 4 times, most recently from 0ad7d4d to 0a949a8 Compare October 23, 2022 20:33
@touilleMan
Copy link
Member Author

@bruvzg can I merge it then ?

@touilleMan touilleMan force-pushed the stringname-in-gdextension-api branch 2 times, most recently from 6174311 to 1e8756c Compare November 8, 2022 22:01
@touilleMan touilleMan merged commit 6d9546f into godotengine:master Nov 8, 2022
@touilleMan touilleMan deleted the stringname-in-gdextension-api branch November 8, 2022 22:03
@Bromeon
Copy link
Contributor

Bromeon commented Nov 8, 2022

It looks like this affects #61968, right?

@touilleMan
Copy link
Member Author

@Bromeon exactly ! I didn't even know about this issue 😄

@Zireael07
Copy link
Contributor

Maybe also will help with #68375

@reduz
Copy link
Member

reduz commented Jan 7, 2023

I feel this PR was kind of pointless. None of these functions are performance critical and since StringName construction still needs to hash the cstring, it would have allowed you to optimize this on the side of the language bind. Now this is probably a lot more complex to implement and a lot more inefficient unless you keep StringNames cached everywhere for everything you do.

@reduz
Copy link
Member

reduz commented Jan 7, 2023

Even worse, if you want to keep a hashtable on the extension side to optimize, how are you going to use the StringName for this?

@reduz
Copy link
Member

reduz commented Jan 7, 2023

Maybe one possibility could be to have a C function to get some uint64_t from the stringname you can use for hashing.

@neikeq
Copy link
Contributor

neikeq commented Jan 7, 2023

... and since StringName construction still needs to hash the cstring, it would have allowed you to optimize this on the side of the language bind.

Even worse, if you want to keep a hashtable on the extension side to optimize, how are you going to use the StringName for this?

I don't understand, can you explain these optimizations in more details? Some pseudo-code may help.

@reduz
Copy link
Member

reduz commented Jan 8, 2023

@neikeq StringName contains a pointer to a string table, which is what makes it fast. If you use it from GDExtension directly its probably going to be slower because you have to call the function pointers to compare it.

I wonder maybe each implementation can implement comparison operators just checking the memory (pointer). If this is the case it should be fine.

Either case, if there is consensus on using StringName for these things from those implementing extensions, I won't oppose. I just feel it may not have been necessary.

@neikeq
Copy link
Contributor

neikeq commented Jan 8, 2023

I wonder maybe each implementation can implement comparison operators just checking the memory (pointer). If this is the case it should be fine.

This is what I do from C#. StringName has a very simple layout, just a pointer.

@reduz
Copy link
Member

reduz commented Jan 8, 2023

@neikeq I have no idea how easy is to expose this to different languages, but if extension implementers are fine doing this, then I don't see the problem with this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants