Previously, the FilterExpression.Expand method would forward the filter
group name to the FilterEntry constructor, which would combine the
group's patterns into one large regex filter. This would result in a
significant decrease in performance, as the regex filters are much
slower than the wildcard filters.
Instead, we can first expand the filter group into its constituent
patterns before presenting them to the FilterEntry constructor. This
preserves their wildcard nature and allows us to take advantage of
faster filtering matching algorithms.
This addresses issue #3395.
The mono profiler indicated that a large percentage of the time was
spent allocating the inputPosStack and patternPosStack arrays. By
replacing these with Stacks, we can avoid this unnecessary overhead.
This provides a workaround for the poor performance of the default
excludes group exhibited by regex filters. While this wildcard pattern
will potentially exclude more files than the previous regex pattern, in
practice this should not often be the case.
This does not resolve the performance issue of the regex filters.
However, I think in general we should try to avoid expensive
application-specific filters since these will affect the performance for
all users that use the default excludes group, whether the application
is present or not.
This concerns issue #3395.
After we removed the tilde expansion in revision c9aa6cf5fb ("Avoid
performing tilde expansion"), the Utility.ExpandEnvironmentVariables
method simply called System.Environment.ExpandEnvironmentVariables. We
can simplify the code by just referencing the built-in method directly.
Previously, the replacement would occur if the provided string did not
end with the platform-dependent directory separator. However, this
utility method is often used to append a trailing slash to URL
specifiers.
This was added in revision 0b442ecdc6, but no usages could be found. A
potential use-case is mentioned in a comment, so the implementation was
moved to the comment.
This was added in revision 6255572c25 ("Added a timestamp value to the
end of dates in the report output for easier parsing"), but no usages
could be found.
When the code following the await can be executed on any thread, it's
recommended to use ConfigureAwait(false) to avoid unnecessary context
switching and potential deadlocks.