Improve performance of SessionHandler::getSpiderID()
authorTim Düsterhus <duesterhus@woltlab.com>
Tue, 1 Mar 2022 11:50:41 +0000 (12:50 +0100)
committerTim Düsterhus <duesterhus@woltlab.com>
Tue, 1 Mar 2022 12:02:05 +0000 (13:02 +0100)
commit96dced2d6197d64f30b6638f3966a8778c586cd6
tree499a2e0610121839bb14650dc135f7ade0bbcc74
parentd2f8e7218f2b204b290d9ba98e68c87d1a5fd0c9
Improve performance of SessionHandler::getSpiderID()

99f28057e7aeb29ed6728917174fd8fc6b7bb1a1 already optimized this to avoid the
need of calling ->getSpiderID() for logged-in users, but guest sessions still
call ->getSpiderID() on every request to look up the legacy session.

This commit massively improves the performance of ->getSpiderID() for all
cases, but especially for requests where no spider can be matched. The latter
previously required a full O(n) search across the spider list and thus was the
worst case situation. This worst case situation likely happened for the vast
majority of guest requests. But even cases where a spider can be matched will
benefit from this.

The improvements are achieved by two things:

1. The size of the cache that needs to be read and unserialized is reduced from
87k to 17k.
2. Instead of searching linearly through the list of spiders, needing to
implicitly call ->__get() twice for each, the matching is performed by an
optimized regular expression that effectively implements a prefix tree. If this
regular expression matches, then the spiderID will be efficiently looked up in
an array that is keyed by the matched string.

Numbers for 10,000 calls to ->getSpiderID() on my computer running PHP 8.1:

- Google Bot: From 0.44s down to 0.14s.
- Firefox 98: From 1.05s down to 0.07s.
wcfsetup/install/files/lib/system/cache/builder/SpiderCacheBuilder.class.php
wcfsetup/install/files/lib/system/session/SessionHandler.class.php