Use Span for String.sprintf, to accelerate vformat not needing to allocate an Array.

This commit is contained in:
Lukas Tenbrink 2025-03-10 17:56:14 +01:00
parent 8b4b93a82e
commit a916325e6a
5 changed files with 14 additions and 9 deletions

View file

@ -5461,7 +5461,7 @@ String String::lpad(int min_length, const String &character) const {
// "fish %s pie" % "frog" // "fish %s pie" % "frog"
// "fish %s %d pie" % ["frog", 12] // "fish %s %d pie" % ["frog", 12]
// In case of an error, the string returned is the error description and "error" is true. // In case of an error, the string returned is the error description and "error" is true.
String String::sprintf(const Array &values, bool *error) const { String String::sprintf(const Span<Variant> &values, bool *error) const {
static const String ZERO("0"); static const String ZERO("0");
static const String SPACE(" "); static const String SPACE(" ");
static const String MINUS("-"); static const String MINUS("-");
@ -5470,7 +5470,7 @@ String String::sprintf(const Array &values, bool *error) const {
String formatted; String formatted;
char32_t *self = (char32_t *)get_data(); char32_t *self = (char32_t *)get_data();
bool in_format = false; bool in_format = false;
int value_index = 0; uint64_t value_index = 0;
int min_chars = 0; int min_chars = 0;
int min_decimals = 0; int min_decimals = 0;
bool in_decimals = false; bool in_decimals = false;

View file

@ -438,7 +438,7 @@ public:
String trim_suffix(const char *p_suffix) const; String trim_suffix(const char *p_suffix) const;
String lpad(int min_length, const String &character = " ") const; String lpad(int min_length, const String &character = " ") const;
String rpad(int min_length, const String &character = " ") const; String rpad(int min_length, const String &character = " ") const;
String sprintf(const Array &values, bool *error) const; String sprintf(const Span<Variant> &values, bool *error) const;
String quote(const String &quotechar = "\"") const; String quote(const String &quotechar = "\"") const;
String unquote() const; String unquote() const;
static String num(double p_num, int p_decimals = -1); static String num(double p_num, int p_decimals = -1);

View file

@ -936,6 +936,10 @@ bool Array::is_read_only() const {
return _p->read_only != nullptr; return _p->read_only != nullptr;
} }
Span<Variant> Array::span() const {
return _p->array.span();
}
Array::Array(const Array &p_from) { Array::Array(const Array &p_from) {
_p = nullptr; _p = nullptr;
_ref(p_from); _ref(p_from);

View file

@ -30,6 +30,7 @@
#pragma once #pragma once
#include "core/templates/span.h"
#include "core/typedefs.h" #include "core/typedefs.h"
#include "core/variant/variant_deep_duplicate.h" #include "core/variant/variant_deep_duplicate.h"
@ -201,6 +202,11 @@ public:
bool is_read_only() const; bool is_read_only() const;
static Array create_read_only(); static Array create_read_only();
Span<Variant> span() const;
operator Span<Variant>() const {
return this->span();
}
Array(const Array &p_base, uint32_t p_type, const StringName &p_class_name, const Variant &p_script); Array(const Array &p_base, uint32_t p_type, const StringName &p_class_name, const Variant &p_script);
Array(const Array &p_from); Array(const Array &p_from);
Array(std::initializer_list<Variant> p_init); Array(std::initializer_list<Variant> p_init);

View file

@ -925,14 +925,9 @@ const Variant::ObjData &Variant::_get_obj() const {
template <typename... VarArgs> template <typename... VarArgs>
String vformat(const String &p_text, const VarArgs... p_args) { String vformat(const String &p_text, const VarArgs... p_args) {
Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported. Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
Array args_array;
args_array.resize(sizeof...(p_args));
for (uint32_t i = 0; i < sizeof...(p_args); i++) {
args_array[i] = args[i];
}
bool error = false; bool error = false;
String fmt = p_text.sprintf(args_array, &error); String fmt = p_text.sprintf(Span(args, sizeof...(p_args)), &error);
ERR_FAIL_COND_V_MSG(error, String(), String("Formatting error in string \"") + p_text + "\": " + fmt + "."); ERR_FAIL_COND_V_MSG(error, String(), String("Formatting error in string \"") + p_text + "\": " + fmt + ".");