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

feat: improve the lifetime of as_ast_kind methods #5506

Closed
shulaoda opened this issue Sep 5, 2024 · 11 comments · Fixed by #5507
Closed

feat: improve the lifetime of as_ast_kind methods #5506

shulaoda opened this issue Sep 5, 2024 · 11 comments · Fixed by #5507
Labels
C-enhancement Category - New feature or request

Comments

@shulaoda
Copy link
Contributor

shulaoda commented Sep 5, 2024

I tried to introduce new methods in PR #5491 , but encountered:

pub fn get_function_like_declaration<'b>(
    node: &AstNode<'b>,
    ctx: &LintContext<'b>,
) -> Option<&'b BindingIdentifier<'b>> {
    let parent = outermost_paren_parent(node, ctx)?;

    if let AstKind::VariableDeclarator(decl) = parent.kind() {
        let ident = decl.id.get_binding_identifier()?;
        Some(ident)
    } else {
        None
    }
}

to

pub fn get_function_like_declaration<'b>(
    node: &AstNode<'b>,
    ctx: &LintContext<'b>,
) -> Option<&'b BindingIdentifier<'b>> {
    let parent = outermost_paren_parent(node, ctx)?;
    let decl = parent.kind().as_variable_declarator()?;

    let ident = decl.id.get_binding_identifier()?;
    Some(ident)
}

error:

temporary value created hererustc[E0515](https://doc.rust-lang.org/error-index.html#E0515)
ast_util.rs(436, 5): original diagnostic
// size = 8, align = 0x8
let parent: &AstNode<'_>

When I changed the method to the following, there was no longer this problem.

pub fn as_variable_declarator(self) -> Option<&'a VariableDeclarator<'a>> {
    if let Self::VariableDeclarator(v) = self {
        Some(v)
    } else {
        None
    }
}

@IWANABETHATGUY cc

@shulaoda shulaoda added the C-enhancement Category - New feature or request label Sep 5, 2024
@shulaoda shulaoda changed the title feat: improve the lifetime of as'ast_kind methods feat: improve the lifetime of as_ast_kind methods Sep 5, 2024
@rzvxa
Copy link
Collaborator

rzvxa commented Sep 5, 2024

You are right, AstKind is cheap to copy - and implements Copy - so this implementation makes sense and is more versatile as it doesn't require the user to clone/copy at the call site.

@IWANABETHATGUY
Copy link
Contributor

You are right, AstKind is cheap to copy - and implements Copy - so this implementation makes sense and is more versatile as it doesn't require the user to clone/copy at the call site.

We don't need to consume itself, just adding the lifetime is enough.

@IWANABETHATGUY
Copy link
Contributor

You are right, AstKind is cheap to copy - and implements Copy - so this implementation makes sense and is more versatile as it doesn't require the user to clone/copy at the call site.

I am ok for both, but as_xxx return reference is default behavior in rust-analyzer

@rzvxa
Copy link
Collaborator

rzvxa commented Sep 5, 2024

You are right, AstKind is cheap to copy - and implements Copy - so this implementation makes sense and is more versatile as it doesn't require the user to clone/copy at the call site.

We don't need to consume itself, just adding the lifetime is enough.

Oh, I just saw this comment, Please ignore my comment on the merged PR.

I was thinking that since both the &AstKind and AstKind have the same size maybe we can save a few CPU cycles by avoiding the extra dereferencing.

@rzvxa
Copy link
Collaborator

rzvxa commented Sep 5, 2024

You are right, AstKind is cheap to copy - and implements Copy - so this implementation makes sense and is more versatile as it doesn't require the user to clone/copy at the call site.

I am ok for both, but as_xxx return reference is default behavior in rust-analyzer

Yes Sir, Since the naming is an anti-pattern this might not be worth doing. Please go ahead and implement it as you see fit.

@IWANABETHATGUY
Copy link
Contributor

You are right, AstKind is cheap to copy - and implements Copy - so this implementation makes sense and is more versatile as it doesn't require the user to clone/copy at the call site.

We don't need to consume itself, just adding the lifetime is enough.

Oh, I just saw this comment, Please ignore my comment on the merged PR.

I was thinking that since both the &AstKind and AstKind have the same size maybe we can save a few CPU cycles by avoiding the extra dereferencing.

ok, that make sence.

@IWANABETHATGUY
Copy link
Contributor

You are right, AstKind is cheap to copy - and implements Copy - so this implementation makes sense and is more versatile as it doesn't require the user to clone/copy at the call site.

I am ok for both, but as_xxx return reference is default behavior in rust-analyzer

Yes Sir, Since the naming is an anti-pattern this might not be worth doing. Please go ahead and implement it as you see fit.

performance goes first,

@rzvxa
Copy link
Collaborator

rzvxa commented Sep 5, 2024

@IWANABETHATGUY No I'm sorry, I was hullucinating. The AstKind type is 16 bytes since it needs 8 bytes for the tag. The implementation with the reference is more performant and better overall.

Please ignore everything I said above.

IWANABETHATGUY added a commit that referenced this issue Sep 5, 2024
@shulaoda shulaoda closed this as completed Sep 5, 2024
@overlookmotel
Copy link
Collaborator

The AstKind type is 16 bytes since it needs 8 bytes for the tag. The implementation with the reference is more performant and better overall.

Out of interest, is your "is more performant" conclusion based on measurement?

I would tend to always make methods on Copy types receive self not &self (unless they're large types, but we probably shouldn't make large types Copy). And I'd assume that's more performant, if both "words" of the type are read in the method, and so need to be read into registers one way or another.

But maybe I'm wrong. If I am, I would very much like to know!

Most of AstKind's method take self.

@rzvxa
Copy link
Collaborator

rzvxa commented Sep 5, 2024

Out of interest, is your "is more performant" conclusion based on measurement?

No Sir, But since it is bigger than a pointer it isn't an open-and-shut case anymore and indirection may or may not be faster. I could've used better wording there.

@shulaoda shulaoda reopened this Sep 6, 2024
@shulaoda shulaoda closed this as completed Sep 6, 2024
@overlookmotel
Copy link
Collaborator

Thanks for coming back. Hmm I wonder which is more performant. Probably (hopefully) these tiny functions will all get inlined anyway, so it'll make no difference in practice. But it'd be useful to know for other cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-enhancement Category - New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants