rust

Is there any performance improvement if I declare this const inside or outside the function?


Since this is an high-called function, is there any difference if I declare const QUERY inside or outside the fn insert()?

impl Player {
    pub async fn insert(
        db: sqlx::PgConnection,
        input: &InputPlayer,
    ) -> Result<Self> {
        const QUERY: &str = r#"INSERT INTO "player" ("team_id", "id", "other_fields") VALUES ($1, $2, $3, $4, $5, $6, $7)"#;

        let result = sqlx::query_as::<_, Self>(QUERY)
            .bind(input.team_id())
            .bind(input.id())
            .bind(input.other())
            .bind(input.other())
            .bind(input.other())
            .bind(input.other())
            .fetch_one(db)
            .await?;

        Ok(result)
    }
}

Solution

  • Let's have a look at the documentation:

    To put it simply, constants are inlined wherever they’re used, making using them identical to simply replacing the name of the const with its value.

    You can confirm this behavior with a simple assembly test. Let's have a look at the following code:

    #[no_mangle]
    pub fn x() -> &'static str {
        const A: &str = "Hello";
        A
    }
    
    const B: &str = "World";
    #[no_mangle]
    pub fn Y() -> &'static str {
        B
    }
    

    This compiles to the following amd64 assembly:

    x:
            lea     rax, [rip + .L__unnamed_1]
            mov     edx, 5
            ret
    
    Y:
            lea     rax, [rip + .L__unnamed_2]
            mov     edx, 5
            ret
    
    .L__unnamed_1:
            .ascii  "Hello"
    
    .L__unnamed_2:
            .ascii  "World"
    

    As you can see, both strings end up being in the same location — stored statically as data in the resulting binary.

    So, a short answer is, no, there is no performance difference, since in both cases it will be a static string living somewhere in the data section of the binary.