From e19d324421a5cfbd480559dfcd9d3a68fc10ae62 Mon Sep 17 00:00:00 2001 From: Niklas Keller Date: Wed, 11 Oct 2017 20:02:00 +0200 Subject: [PATCH] Cache last parsed host Artax re-parses the same host multiple times, because it's parsed in Artax, then parsed in HttpSocketPool, then parsed in BasicSocketPool. All calls happen synchronously, so it makes sense to cache exactly the last parsed host. Other similar uses might benefit, too. I'm not sure about benefits for non-benchmarks, but it brings significant benefits in benchmark situations. --- src/Uri.php | 47 +++++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/src/Uri.php b/src/Uri.php index cf0601e..87ffba4 100644 --- a/src/Uri.php +++ b/src/Uri.php @@ -6,6 +6,11 @@ * Provides URI parsing and can resolve URIs. */ final class Uri { + private static $lastHost; + private static $lastHostNormalized; + private static $lastHostIpV4; + private static $lastHostIpV6; + private $defaultPortMap = [ "http" => 80, "https" => 443, @@ -45,23 +50,33 @@ public function __construct(string $uri) { // "schemes are case-insensitive" $this->scheme = \strtolower($this->scheme); - // http://www.apps.ietf.org/rfc/rfc3986.html#sec-3.2.2 - // "Although host is case-insensitive, producers and normalizers should use lowercase for - // registered names and hexadecimal addresses for the sake of uniformity" - if ($inAddr = @\inet_pton(\trim($this->host, "[]"))) { - $this->host = \strtolower($this->host); - - if (isset($inAddr[4])) { - $this->isIpV6 = true; - } else { - $this->isIpV4 = true; - } - } elseif ($this->host) { - try { - $this->host = normalizeDnsName($this->host); - } catch (InvalidDnsNameException $e) { - throw new InvalidUriException("Invalid URI: Invalid host: {$this->host}", 0, $e); + if ($this->host === self::$lastHost) { + $this->host = self::$lastHostNormalized; + $this->isIpV4 = self::$lastHostIpV4; + $this->isIpV6 = self::$lastHostIpV6; + } else { + // http://www.apps.ietf.org/rfc/rfc3986.html#sec-3.2.2 + // "Although host is case-insensitive, producers and normalizers should use lowercase for + // registered names and hexadecimal addresses for the sake of uniformity" + if ($inAddr = @\inet_pton(\trim($this->host, "[]"))) { + $this->host = \strtolower($this->host); + + if (isset($inAddr[4])) { + $this->isIpV6 = true; + } else { + $this->isIpV4 = true; + } + } elseif ($this->host) { + try { + $this->host = normalizeDnsName($this->host); + } catch (InvalidDnsNameException $e) { + throw new InvalidUriException("Invalid URI: Invalid host: {$this->host}", 0, $e); + } } + + self::$lastHostNormalized = $this->host; + self::$lastHostIpV4 = $this->isIpV4; + self::$lastHostIpV6 = $this->isIpV6; } if ($this->port === 0) {