Github user ChristopherSchultz commented on the issue:
https://github.com/apache/tomcat/pull/108
The performance of this strategy can be significantly improved by
converting the "version number" into a value that can more easily be compared
against other values. This can be done in several ways, some building on others
(i.e. smaller changes) and some with significant changes.
The most obvious performance optimization is to cache the compiled regex
`Pattern` objects: you will be doing a lot of tokenizing on `/\./`, so compile
it once and use it many times.
The second most obvious performance optimization is to stop using regular
expressions entirely. When searching for a single character, it's much faster
to write your own tokenizer because regular expressions inherently have more
overhead (because they are so flexible). The code is not as straightforward
(and I'm happy to see that you provided an easy-to-follow patch, here) but in
this case, speed is in fact important as Mark notes: this code will be executed
for every request whose URL might match the context.
The third most obvious performance improvement would be to store the
tokenized version number as an array and, in `compareTo` simply compare the
individual elements of the arrays in each object. Then you don't have to
tokenize during each compare.
Finally, instead of re-computing the "version" difference every time, a
representative value could be built for the version number that can be quickly
compared against another value. For example, let's take the versions `1.0.9`
and `1.0.10` for example. One strategy would be to normalize each part of the
version number to have some kind of "maximum number of digits." Let's pick
4-digits and see how to do this:
1. Tokenize `1.0.9` into [1, 0, 9]
2. Convert to string with 4-digits for each version component:
`000100000009`
3. Tokenize `1.0.10` into [1, 0, 10]
4. Convert to string with 4-digits for each version component:
`000100000010`
5. Compare the strings alphabetically (`String.compareTo`)
Now, simply more steps 1-2 into the constructor of the `ContextName` class
and then `ContextName.compareTo` becomes a simple comparison of the normalized
version number.
One can also do this with integral values instead of `Strings` and the
comparison becomes even faster, but you run the risk of running out of digits
if the padding is too wide (e.g. 4-digit padding with a version number like
`1.0.9.1` yields `1000200030001` which is `>` `Integer.MAX_VALUE` so you'd have
to switch to a `long` value. Comparing `long` values is faster than comparing
`String` values, but at some point you run out of digits in a `long` value as
well.
Anyway, there is lots of room for improvement, here, and I think it *does*
make sense to support "traditional" version numbering. Note that this will
represent a backward-*in*compatible change, and those relying upon the current
alphabetical-ordering will need to adjust their expectations.
---
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]