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

derive: unify filter argument handling #318

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

Kijewski
Copy link
Collaborator

No description provided.

Comment on lines 1075 to 1076
"unexpected argument{} in `{name}` filter",
if args.len() == 2 { "" } else { "s" },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"unexpected argument{} in `{name}` filter",
if args.len() == 2 { "" } else { "s" },
"expected 1 argument in `{name}` filter, found {}",
args.len(),

Better than handling plural: not handling plural. :D

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, but the "1" is not true in all cases. :) I reworded the message, and implemented it with less magic. 🪄

@Kijewski Kijewski force-pushed the pr-unify-filter-arg branch from 98e1791 to 6a95aee Compare January 21, 2025 18:39
@GuillaumeGomez
Copy link
Contributor

Conflict. I'll approve once updated otherwise it doesn't work. :')

@Kijewski
Copy link
Collaborator Author

Would conflict with #311, too. I'll rebase it after #311 is merged. :)

@Kijewski Kijewski force-pushed the pr-unify-filter-arg branch 2 times, most recently from b4dfbbe to a9166d3 Compare January 24, 2025 22:57
@Kijewski
Copy link
Collaborator Author

I expanded slightly on the initial idea.

Comment on lines -289 to -291
if BUILTIN_FILTERS_NEED_ALLOC.contains(&name) {
ensure_filter_has_feature_alloc(ctx, name, node)?;
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check was in the wrong method. Moved to _visit_builtin_filter.

@@ -303,43 +297,18 @@ impl<'a> Generator<'a, '_> {
buf: &mut Buffer,
name: &str,
args: &[WithSpan<'_, Expr<'a>>],
generics: &[WithSpan<'_, TyGenerics<'_>>],
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No built-in filter needs generics.

return self._visit_builtin_filter(ctx, buf, name, args, generics, node);
"urlencode" | "urlencode_strict" => Self::_visit_urlencode_filter,
name if BUILTIN_FILTERS.contains(&name) => Self::_visit_builtin_filter,
"value" => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why moving "value" below the name check?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You still didn't answer to this one. 😉

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved the filters that return to the bottom, to make it easier to follow the code. In the last/current implementation it's strictly alphabetical again. :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case I don't think it's the right way to do it. In the (unlikely) case we added (by mistake) value into BUILTIN_FILTERS, then we'd get no way of noticing that the real value filter is not called until the tests failed.

But anyway, in the current case I think the code can be improved a bit (adding suggestion comment below). 😛

"linebreaks" => Self::_visit_linebreaks_filter,
"linebreaksbr" => Self::_visit_linebreaksbr_filter,
"paragraphbreaks" => Self::_visit_paragraphbreaks_filter,
"linebreaks" | "linebreaksbr" | "paragraphbreaks" => Self::_visit_linebreaks_filters,
Copy link
Contributor

@GuillaumeGomez GuillaumeGomez Jan 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we're back giving the filter name as argument? That's one extra argument we could skip but if you think it's better this way, then let's go with it.

_ => {
return self._visit_custom_filter(ctx, buf, name, args, generics);
}
type Filter = for<'a> fn(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Considering the amount of code it adds, what's the perf gain?

@Kijewski
Copy link
Collaborator Author

$ cargo bench --bench filters
noop                    time:   [44.123 µs 44.205 µs 44.283 µs]
                        change: [+0.8450% +1.2321% +1.6350%] (p = 0.00 < 0.05)
                        Change within noise threshold.

no_filters              time:   [51.914 µs 52.539 µs 53.235 µs]
                        change: [+0.0880% +0.9181% +1.8833%] (p = 0.05 < 0.05)
                        Change within noise threshold.

few_filters             time:   [76.035 µs 76.535 µs 76.984 µs]
                        change: [+1.2029% +1.8326% +2.4187%] (p = 0.00 < 0.05)
                        Performance has regressed.

all_filters             time:   [96.863 µs 97.574 µs 98.471 µs]
                        change: [-8.9618% -8.4126% -7.7142%] (p = 0.00 < 0.05)
                        Performance has improved.

some_filters_twice      time:   [70.936 µs 71.177 µs 71.383 µs]
                        change: [-8.5514% -8.1406% -7.7478%] (p = 0.00 < 0.05)
                        Performance has improved.

The first two tests are only to measure that my CPU is probably running hotter on the second run. (It shows +216.0°C, but I'm fairly confident that the measurement is incorrect. :D)

@GuillaumeGomez
Copy link
Contributor

I'm shared here: the code complexity increases a lot, and although % improvement is noticeable, we're talking in µs. I don't think it's noticeable for a user and therefore, I don't think it's worth the extra complexity.

@Kijewski Kijewski force-pushed the pr-unify-filter-arg branch from e611aa3 to 6ac3ac0 Compare January 25, 2025 17:43
@Kijewski
Copy link
Collaborator Author

Back to a simple match. The timings are actually about the same.

Comment on lines 265 to 271
name if BUILTIN_FILTERS.contains(&name) => Self::_visit_builtin_filter,
"value" => {
return self._visit_value(ctx, buf, args, generics, node, "`value` filter");
}
_ => {
return self._visit_custom_filter(ctx, buf, name, args, generics);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
name if BUILTIN_FILTERS.contains(&name) => Self::_visit_builtin_filter,
"value" => {
return self._visit_value(ctx, buf, args, generics, node, "`value` filter");
}
_ => {
return self._visit_custom_filter(ctx, buf, name, args, generics);
}
"value" => {
return self._visit_value(ctx, buf, args, generics, node, "`value` filter");
}
name => if BUILTIN_FILTERS.contains(&name) {
Self::_visit_builtin_filter
} else {
return self._visit_custom_filter(ctx, buf, name, args, generics);
},

This allows to remove one arm and have the contains call to be done after all other strings have been checked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants