Skip to content

8353013: java.net.URI.create(String) may have low performance to scan the host/domain name from URI string when the hostname starts with number #24295

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion src/java.base/share/classes/java/net/URI.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -3426,6 +3426,20 @@ private int scanByte(int start, int n)
int p = start;
int q = scan(p, n, L_DIGIT, H_DIGIT);
if (q <= p) return q;

// Handle leading zeros
int i = p, j;
while ((j = scan(i, q, '0')) > i) i = j;

// Calculate the number of significant digits (after leading zeros)
int significantDigitsNum = q - i;

// If no significant digits (all zeros), the value is 0
if (significantDigitsNum < 3) return q; // definitely < 255

// If more than 3 significant digits, it's definitely > 255
if (significantDigitsNum > 3) return p;

if (Integer.parseInt(input, p, q, 10) > 255) return p;
return q;
}
Expand Down
27 changes: 25 additions & 2 deletions test/jdk/java/net/URI/Test.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand All @@ -24,7 +24,7 @@
/* @test
* @summary Unit test for java.net.URI
* @bug 4464135 4505046 4503239 4438319 4991359 4866303 7023363 7041800
* 7171415 6339649 6933879 8037396 8272072 8051627 8297687
* 7171415 6339649 6933879 8037396 8272072 8051627 8297687 8353013
* @author Mark Reinhold
*/

Expand Down Expand Up @@ -1620,6 +1620,7 @@ static void bugs() {
b8051627();
b8272072();
b8297687();
b8353013();
}

private static void b8297687() {
Expand Down Expand Up @@ -1786,6 +1787,28 @@ private static void b8272072() {
}
}

// 8353013 - java.net.URI.create(String) may have low performance to scan the host/domain name from
// URI string when the hostname starts with number
Copy link
Contributor

@AlanBateman AlanBateman Apr 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment looks a bit out of place in a unit test. I think start with a JMH benchmark and change the comment in the unit test to make it clearer that it's providing more test coverage for cases where the authority component of a hierarchical URI has a host component that starts with a number.

Copy link
Author

@rk-kmr rk-kmr Apr 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I have updated the comment and added a JMH benchmark.

## Before
Benchmark                                                      (uri)  Mode  Cnt     Score    Error  Units
URIAuthorityParsingBenchmark.create  https://98765432101.abc.xyz.com  avgt   15  1495.273 ± 86.157  ns/op
URIAuthorityParsingBenchmark.create  https://ABCDEFGHIJK.abc.xyz.com  avgt   15   363.048 ±  6.510  ns/op

## After
Benchmark                                                    Mode  Cnt    Score    Error  Units
Benchmark                                                      (uri)  Mode  Cnt    Score    Error  Units
URIAuthorityParsingBenchmark.create  https://98765432101.abc.xyz.com  avgt   15  377.741 ± 10.497  ns/op
URIAuthorityParsingBenchmark.create  https://ABCDEFGHIJK.abc.xyz.com  avgt   15  334.215 ±  2.148  ns/op

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't is suspicious that non-number case got speedup too?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we should consider a 30ns speed up in a single run of the benchmark on a single node as significant.

private static void b8353013() {
testCreate("https://0.0.0.1").s("https").h("0.0.0.1").p("").z();
testCreate("https://00.0.0.2").s("https").h("00.0.0.2").p("").z();
testCreate("https://000.0.0.3").s("https").h("000.0.0.3").p("").z();
testCreate("https://0000.0.0.4").s("https").h("0000.0.0.4").p("").z();

testCreate("https://00000.0.0.5").s("https").h("00000.0.0.5").p("").z();
testCreate("https://00001.0.0.6").s("https").h("00001.0.0.6").p("").z();

testCreate("https://01.0.0.1").s("https").h("01.0.0.1").p("").z();

testCreate("https://111111.2.3.com").s("https").h("111111.2.3.com").p("").z();

testCreate("https://1.example.com").s("https").h("1.example.com").p("").z();
testCreate("https://12.example.com").s("https").h("12.example.com").p("").z();
testCreate("https://123.example.com").s("https").h("123.example.com").p("").z();
testCreate("https://1234.example.com").s("https").h("1234.example.com").p("").z();
testCreate("https://12345.example.com").s("https").h("12345.example.com").p("").z();
}

public static void main(String[] args) throws Exception {
switch (args.length) {

Expand Down