From a916325e6a1d0bed789b8e3ebfc86f681762ba9a Mon Sep 17 00:00:00 2001 From: Lukas Tenbrink Date: Mon, 10 Mar 2025 17:56:14 +0100 Subject: [PATCH] Use `Span` for `String.sprintf`, to accelerate `vformat` not needing to allocate an `Array`. --- core/string/ustring.cpp | 4 ++-- core/string/ustring.h | 2 +- core/variant/array.cpp | 4 ++++ core/variant/array.h | 6 ++++++ core/variant/variant.h | 7 +------ 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index 45d8497af81..eb37fdd67e1 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -5461,7 +5461,7 @@ String String::lpad(int min_length, const String &character) const { // "fish %s pie" % "frog" // "fish %s %d pie" % ["frog", 12] // 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 &values, bool *error) const { static const String ZERO("0"); static const String SPACE(" "); static const String MINUS("-"); @@ -5470,7 +5470,7 @@ String String::sprintf(const Array &values, bool *error) const { String formatted; char32_t *self = (char32_t *)get_data(); bool in_format = false; - int value_index = 0; + uint64_t value_index = 0; int min_chars = 0; int min_decimals = 0; bool in_decimals = false; diff --git a/core/string/ustring.h b/core/string/ustring.h index 9bcc68064f8..9ca568d3e37 100644 --- a/core/string/ustring.h +++ b/core/string/ustring.h @@ -438,7 +438,7 @@ public: String trim_suffix(const char *p_suffix) const; String lpad(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 &values, bool *error) const; String quote(const String "echar = "\"") const; String unquote() const; static String num(double p_num, int p_decimals = -1); diff --git a/core/variant/array.cpp b/core/variant/array.cpp index 7b234c35d2b..8d892422df8 100644 --- a/core/variant/array.cpp +++ b/core/variant/array.cpp @@ -936,6 +936,10 @@ bool Array::is_read_only() const { return _p->read_only != nullptr; } +Span Array::span() const { + return _p->array.span(); +} + Array::Array(const Array &p_from) { _p = nullptr; _ref(p_from); diff --git a/core/variant/array.h b/core/variant/array.h index 539c24df67e..2f051227483 100644 --- a/core/variant/array.h +++ b/core/variant/array.h @@ -30,6 +30,7 @@ #pragma once +#include "core/templates/span.h" #include "core/typedefs.h" #include "core/variant/variant_deep_duplicate.h" @@ -201,6 +202,11 @@ public: bool is_read_only() const; static Array create_read_only(); + Span span() const; + operator Span() 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_from); Array(std::initializer_list p_init); diff --git a/core/variant/variant.h b/core/variant/variant.h index cf77a3d8a3c..b3db8d03e2c 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -925,14 +925,9 @@ const Variant::ObjData &Variant::_get_obj() const { template 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. - 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; - 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 + ".");