Skip to content

Commit

Permalink
prost-build: optimise derived prost::Name
Browse files Browse the repository at this point in the history
When deriving prost::Name, prost-bulid generates the following code
for full_name and type_url methods:

    fn full_name() -> ::prost::alloc::string::String {
        ::prost::alloc::format!(
            "some.package.{0}", Self::NAME
        )
    }
    fn type_url() -> ::prost::alloc::string::String {
        ::prost::alloc::format!(
            "example.com/{0}", Self::full_name()
        )
    }

With those definitions, type_url:
- allocates a new temporary string,
- formats text into that string,
- allocates another string,
- and once again formats text into that string.

Most of those operations can be done at build time with only a single
string allocation being necessary in type_url method.

Change the generated code such that no formatting happens at run time
and no temporary strings are allocated in type_url, specifically:

    fn full_name() -> ::prost::alloc::string::String {
        "some.package.MessageName".into()
    }
    fn type_url() -> ::prost::alloc::string::String {
        "example.com/some.package.MessageName"
    }

Furthermore, unconditionally derive type_url even if no domain is
specified such that default definition (which uses temporary strings
and formatting) isn’t used.
  • Loading branch information
mina86 committed Dec 7, 2023
1 parent 907e9f6 commit 1096f9e
Showing 1 changed file with 17 additions and 14 deletions.
31 changes: 17 additions & 14 deletions prost-build/src/code_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,26 +293,29 @@ impl<'a> CodeGenerator<'a> {
));

let prost_path = self.config.prost_path.as_deref().unwrap_or("::prost");
let string_path = format!("{}::alloc::string::String", prost_path);
let format_path = format!("{}::alloc::format", prost_path);
let string_path = format!("{prost_path}::alloc::string::String");

self.buf.push_str(&format!(
r#"fn full_name() -> {string_path} {{
{format_path}!("{}{}{}{}{{}}", Self::NAME)
}}"#,
let full_name = [
self.package.trim_matches('.'),
if self.package.is_empty() { "" } else { "." },
self.type_path.join("."),
&self.type_path.join("."),
if self.type_path.is_empty() { "" } else { "." },
message_name,
]
.concat();
let domain_name = self
.config
.type_name_domains
.get_first(fq_message_name)
.map_or("", |name| name.as_str());

self.buf.push_str(&format!(
r#"fn full_name() -> {string_path} {{ "{full_name}".into() }}"#,
));

if let Some(domain_name) = self.config.type_name_domains.get_first(fq_message_name) {
self.buf.push_str(&format!(
r#"fn type_url() -> {string_path} {{
{format_path}!("{domain_name}/{{}}", Self::full_name())
}}"#,
));
}
self.buf.push_str(&format!(
r#"fn type_url() -> {string_path} {{ "{domain_name}/{full_name}".into() }}"#,
));

self.depth -= 1;
self.buf.push_str("}\n");
Expand Down

0 comments on commit 1096f9e

Please sign in to comment.