schlosna opened a new pull request, #347:
URL: https://github.com/apache/httpcomponents-core/pull/347

   Check input colon count before performing IPv6 regex validation.
   
   `org.apache.hc.core5.net.InetAddressUtils.isIPv6Address` is used when 
constructing the `host` header for requests, and currently allocates a regex 
matcher when checking if the provided address is an IPv6 address. This is 
generates excess garbage and CPU cycles, especially in environments with mostly 
IPv4 addresses. By checking the colon count first, we see a 50x improvement 
checking `InetAddressUtils.isIPv6Address` for an IPv4 address.
   
   
   The specific call backtrace seen looks like:
   ```
   void java.util.regex.Matcher.<init>(Pattern, CharSequence)
      Matcher java.util.regex.Pattern.matcher(CharSequence)
      boolean 
org.apache.hc.core5.net.InetAddressUtils.isIPv6HexCompressedAddress(String)
         boolean org.apache.hc.core5.net.InetAddressUtils.isIPv6Address(String)
         void org.apache.hc.core5.net.Host.format(StringBuilder, NamedEndpoint)
         void org.apache.hc.core5.net.URIAuthority.format(StringBuilder, 
URIAuthority)
            String org.apache.hc.core5.net.URIAuthority.format(URIAuthority)
            String org.apache.hc.core5.net.URIAuthority.toString()
            String java.util.Objects.toString(Object, String)
            void org.apache.hc.core5.http.message.BasicHeader.<init>(String, 
Object, boolean)
            void org.apache.hc.core5.http.message.BasicHeader.<init>(String, 
Object)
            void 
org.apache.hc.core5.http.message.BasicHttpRequest.addHeader(String, Object)
            void 
org.apache.hc.core5.http.protocol.RequestTargetHost.process(HttpRequest, 
EntityDetails, HttpContext)
            void 
org.apache.hc.core5.http.protocol.DefaultHttpProcessor.process(HttpRequest, 
EntityDetails, HttpContext)
            ClassicHttpResponse 
org.apache.hc.client5.http.impl.classic.ProtocolExec.execute(ClassicHttpRequest,
 ExecChain$Scope, ExecChain)
            ClassicHttpResponse 
org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ClassicHttpRequest,
 ExecChain$Scope)
            ClassicHttpResponse 
org.apache.hc.client5.http.impl.classic.ExecChainElement$1.proceed(ClassicHttpRequest,
 ExecChain$Scope)
            ClassicHttpResponse 
org.apache.hc.client5.http.impl.classic.RedirectExec.execute(ClassicHttpRequest,
 ExecChain$Scope, ExecChain)
            ClassicHttpResponse 
org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ClassicHttpRequest,
 ExecChain$Scope)
            CloseableHttpResponse 
org.apache.hc.client5.http.impl.classic.InternalHttpClient.doExecute(HttpHost, 
ClassicHttpRequest, HttpContext)
            CloseableHttpResponse 
org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(ClassicHttpRequest,
 HttpContext)
            CloseableHttpResponse 
org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(ClassicHttpRequest)
   ```
   
   I wrote some 
[Ipv6FormatBenchmarks](https://github.com/schlosna/httpclient-format-performance/blob/develop/src/jmh/java/com/github/schlosna/Ipv6FormatBenchmarks.java)
 showing original and improved:
   
   From `JDK 11.0.13, OpenJDK 64-Bit Server VM, 11.0.13+8-LTS` on `Intel(R) 
Xeon(R) Platinum 8259CL CPU @ 2.50GHz`:
   ```
   Benchmark                                                              
(address)  Mode  Cnt    Score   Error   Units
   Ipv6FormatBenchmarks.isIPv6Address_original                            
127.0.0.1  avgt    2  395.333           ns/op
   Ipv6FormatBenchmarks.isIPv6Address_original:·gc.alloc.rate.norm        
127.0.0.1  avgt    2  440.000            B/op
   Ipv6FormatBenchmarks.isIPv6Address_original                      
0:0:0:0:0:0:0:1  avgt    2  425.793           ns/op
   Ipv6FormatBenchmarks.isIPv6Address_original:·gc.alloc.rate.norm  
0:0:0:0:0:0:0:1  avgt    2  208.000            B/op
   Ipv6FormatBenchmarks.isIPv6Address_improved                            
127.0.0.1  avgt    2   15.780           ns/op
   Ipv6FormatBenchmarks.isIPv6Address_improved:·gc.alloc.rate.norm        
127.0.0.1  avgt    2   ≈ 10⁻⁶            B/op
   Ipv6FormatBenchmarks.isIPv6Address_improved                      
0:0:0:0:0:0:0:1  avgt    2  430.078           ns/op
   Ipv6FormatBenchmarks.isIPv6Address_improved:·gc.alloc.rate.norm  
0:0:0:0:0:0:0:1  avgt    2  208.000            B/op
   ```
   
   
   Seen in JFR profiles before changes:
   
![image](https://user-images.githubusercontent.com/54594/166573589-2c814d53-9639-4b14-82d0-9238f285be0b.png)
   
   
![image](https://user-images.githubusercontent.com/54594/166573845-b556e2ad-6b26-48d2-a2ee-2a01e4316c8b.png)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscr...@hc.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@hc.apache.org
For additional commands, e-mail: dev-h...@hc.apache.org

Reply via email to