From f986f63015998f621a6714e61e863522e9cfe2bc Mon Sep 17 00:00:00 2001 From: Robin Leroy Date: Fri, 2 Feb 2024 18:22:18 +0100 Subject: [PATCH 01/21] Remove the shim made redundant by #657 --- .../props/ShimUnicodePropertyFactory.java | 22 ++----------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/unicodetools/src/main/java/org/unicode/props/ShimUnicodePropertyFactory.java b/unicodetools/src/main/java/org/unicode/props/ShimUnicodePropertyFactory.java index cc4f8aa26..8fdbd45b2 100644 --- a/unicodetools/src/main/java/org/unicode/props/ShimUnicodePropertyFactory.java +++ b/unicodetools/src/main/java/org/unicode/props/ShimUnicodePropertyFactory.java @@ -57,6 +57,8 @@ public ShimUnicodePropertyFactory(IndexUnicodeProperties factory) { for (String propName : factory.getAvailableNames()) { UnicodeProperty prop = factory.getProperty(propName); switch (propName) { + // The default is in BidiMirroring.txt, but TUP incorrectly has it as + // . case "Bidi_Mirroring_Glyph": prop = replaceCpValues( @@ -72,12 +74,6 @@ public ShimUnicodePropertyFactory(IndexUnicodeProperties factory) { replaceCpValues( prop, (cp, oldValue) -> fixFC_NFKC_Closure(cp, oldValue)); - break; - case "Joining_Type": - prop = replaceCpValues(prop, (cp, oldValue) -> fixJoining_Type(cp, oldValue)); - break; - case "Joining_Group": - prop = modifyJoining_Group(prop); break; case "Jamo_Short_Name": prop = modifyJamo_Short_Name(prop); @@ -316,25 +312,11 @@ private String fixFC_NFKC_Closure(int cp, String oldValue) { } } - // Joining_Type needs fix in IUP - private String fixJoining_Type(int cp, String oldValue) { - if (defaultTransparent.contains(cp) && "Non_Joining".equals(oldValue)) { - return "Transparent"; - } else { - return oldValue; - } - } - // Jamo_Short_Name needs fix in IUP private UnicodeProperty modifyJamo_Short_Name(UnicodeProperty prop) { return copyPropReplacingMap(prop, prop.getUnicodeMap().put('ᄋ', "")); } - // Joining_Group needs fix in IUP (really, in UCD data) - private UnicodeProperty modifyJoining_Group(UnicodeProperty prop) { - return copyPropReplacingMap(prop, prop.getUnicodeMap().put('ۃ', "Teh_Marbuta_Goal")); - } - /** Very useful. May already be in ICU, but not sure. */ public boolean equalsString(int codepoint, String value) { return codepoint == value.codePointAt(0) From 98c22137490aaf8f9d2837c44306e4da77f449d2 Mon Sep 17 00:00:00 2001 From: Robin Leroy Date: Fri, 2 Feb 2024 19:25:06 +0100 Subject: [PATCH 02/21] =?UTF-8?q?What=E2=80=99s=20in=20a=20Name=3F=20That?= =?UTF-8?q?=20which=20we=20call=20a=20=F0=9F=8C=B9=20ROSE=20/=20By=20any?= =?UTF-8?q?=20other=20Name=20would=20smell=20as=20sweet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../unicode/props/IndexUnicodeProperties.java | 55 ++++++++++++------- .../props/ShimUnicodePropertyFactory.java | 15 +++-- 2 files changed, 44 insertions(+), 26 deletions(-) diff --git a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java index 12ab60a99..76832929b 100644 --- a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java +++ b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java @@ -10,7 +10,6 @@ import com.ibm.icu.text.Normalizer2; import com.ibm.icu.text.Transform; import com.ibm.icu.text.Transliterator; -import com.ibm.icu.text.UTF16; import com.ibm.icu.text.UnicodeSet; import com.ibm.icu.util.ICUException; import com.ibm.icu.util.VersionInfo; @@ -29,6 +28,7 @@ import java.util.EnumMap; import java.util.EnumSet; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; @@ -535,28 +535,12 @@ private UnicodeMap getCachedMap(UcdProperty prop2, String sourceFileName public static String getResolvedValue( IndexUnicodeProperties props, UcdProperty prop, String codepoint, String value) { - if (value == null && props != null) { - if (getResolvedDefaultValueType(prop) == DefaultValueType.CODE_POINT) { - return codepoint; - } - } - if (prop == UcdProperty.Name && value != null && value.endsWith("-#")) { - return value.substring(0, value.length() - 1) + Utility.hex(codepoint); - } - return value; + return props.getProperty(prop).getValue(codepoint.codePointAt(0)); } public static String getResolvedValue( IndexUnicodeProperties props, UcdProperty prop, int codepoint, String value) { - if (value == null && props != null) { - if (getResolvedDefaultValueType(prop) == DefaultValueType.CODE_POINT) { - return UTF16.valueOf(codepoint); - } - } - if (prop == UcdProperty.Name && value != null && value.endsWith("-#")) { - return value.substring(0, value.length() - 1) + Utility.hex(codepoint); - } - return value; + return props.getProperty(prop).getValue(codepoint); } UnicodeMap nameMap; @@ -693,15 +677,44 @@ class IndexUnicodeProperty extends UnicodeProperty.BaseProperty { } } + @Override protected UnicodeMap _getUnicodeMap() { + var raw = _getRawUnicodeMap(); + if (prop == UcdProperty.Name + || raw.containsValue("") + || raw.containsValue("")) { + UnicodeMap newMap = new UnicodeMap<>(); + for (UnicodeMap.EntryRange range : raw.entryRanges()) { + if (DefaultValueType.forString(range.value) == DefaultValueType.CODE_POINT + || (prop == UcdProperty.Name && range.value.endsWith("#"))) { + for (int c = range.codepoint; c <= range.codepointEnd; ++c) { + newMap.putAll(c, c, _getValue(c)); + } + } else { + newMap.putAll(range.codepoint, range.codepointEnd, range.value); + } + } + return newMap; + } else { + return raw; + } + } + + protected UnicodeMap _getRawUnicodeMap() { return load(prop); } @Override protected String _getValue(int codepoint) { - final String result = _getUnicodeMap().get(codepoint); + final String result = _getRawUnicodeMap().get(codepoint); + if (!seen.contains(prop)) { + seen.add(prop); + System.out.println(prop); + } if (DefaultValueType.forString(result) == DefaultValueType.CODE_POINT) { return Character.toString(codepoint); + } else if (prop == UcdProperty.Name && result != null && result.endsWith("#")) { + return result.substring(0, result.length() - 1) + Utility.hex(codepoint); } else { return result; } @@ -757,4 +770,6 @@ public UnicodeProperty getProperty(UcdProperty ucdProperty) { public UnicodeSet loadBinary(UcdProperty ucdProp) { return load(ucdProp).getSet(Binary.Yes.toString()); } + + static Set seen = new HashSet<>(); } diff --git a/unicodetools/src/main/java/org/unicode/props/ShimUnicodePropertyFactory.java b/unicodetools/src/main/java/org/unicode/props/ShimUnicodePropertyFactory.java index 8fdbd45b2..d51ba46c9 100644 --- a/unicodetools/src/main/java/org/unicode/props/ShimUnicodePropertyFactory.java +++ b/unicodetools/src/main/java/org/unicode/props/ShimUnicodePropertyFactory.java @@ -57,9 +57,9 @@ public ShimUnicodePropertyFactory(IndexUnicodeProperties factory) { for (String propName : factory.getAvailableNames()) { UnicodeProperty prop = factory.getProperty(propName); switch (propName) { - // The default is in BidiMirroring.txt, but TUP incorrectly has it as - // . case "Bidi_Mirroring_Glyph": + // The default is in BidiMirroring.txt, but TUP incorrectly has it as + // . prop = replaceCpValues( prop, @@ -70,6 +70,8 @@ public ShimUnicodePropertyFactory(IndexUnicodeProperties factory) { prop = replaceValues(prop, oldValue -> oldValue == null ? "\u0000" : oldValue); break; case "FC_NFKC_Closure": + // The default is in PropertyValueAliases.txt, but TUP incorrectly + // has it as . prop = replaceCpValues( prop, (cp, oldValue) -> fixFC_NFKC_Closure(cp, oldValue)); @@ -79,7 +81,10 @@ public ShimUnicodePropertyFactory(IndexUnicodeProperties factory) { prop = modifyJamo_Short_Name(prop); break; case "Name": - // prop = modifyName(prop); + // TUP reports the special label as the value of the Name + // property. This is incorrect, the actual value of the Name property is "" for + // those, see https://www.unicode.org/versions/latest/ch04.pdf#G135245 and + // https://www.unicode.org/reports/tr44/#Name. prop = replaceCpValues(prop, (cp, x) -> fixName(cp, x)); break; case "Numeric_Value": @@ -297,15 +302,13 @@ private String fixNumericValue(String value) { private String fixName(int cp, String value) { if (control.contains(cp)) { return ""; - } else if (value != null && value.contains("#")) { - return value.replace("#", Utility.hex(cp, 4)); } else { return value; } } private String fixFC_NFKC_Closure(int cp, String oldValue) { - if (oldValue.equals("") || equalsString(cp, oldValue)) { + if (equalsString(cp, oldValue)) { return null; } else { return oldValue; From 69c40c0d14b5e4f5ece651389d3007749a8dbc87 Mon Sep 17 00:00:00 2001 From: Robin Leroy Date: Fri, 2 Feb 2024 19:33:56 +0100 Subject: [PATCH 03/21] all of one code point --- .../src/main/java/org/unicode/props/IndexUnicodeProperties.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java index 76832929b..d5d10df6f 100644 --- a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java +++ b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java @@ -688,7 +688,7 @@ protected UnicodeMap _getUnicodeMap() { if (DefaultValueType.forString(range.value) == DefaultValueType.CODE_POINT || (prop == UcdProperty.Name && range.value.endsWith("#"))) { for (int c = range.codepoint; c <= range.codepointEnd; ++c) { - newMap.putAll(c, c, _getValue(c)); + newMap.put(c, _getValue(c)); } } else { newMap.putAll(range.codepoint, range.codepointEnd, range.value); From 037bf989062e71b4a5bc5c6f535231f1733531df Mon Sep 17 00:00:00 2001 From: Robin Leroy Date: Fri, 2 Feb 2024 19:35:36 +0100 Subject: [PATCH 04/21] invest in a function, remove traces --- .../unicode/props/IndexUnicodeProperties.java | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java index d5d10df6f..9377f4448 100644 --- a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java +++ b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java @@ -688,7 +688,7 @@ protected UnicodeMap _getUnicodeMap() { if (DefaultValueType.forString(range.value) == DefaultValueType.CODE_POINT || (prop == UcdProperty.Name && range.value.endsWith("#"))) { for (int c = range.codepoint; c <= range.codepointEnd; ++c) { - newMap.put(c, _getValue(c)); + newMap.put(c, resolveValue(range.value, c)); } } else { newMap.putAll(range.codepoint, range.codepointEnd, range.value); @@ -707,16 +707,16 @@ protected UnicodeMap _getRawUnicodeMap() { @Override protected String _getValue(int codepoint) { final String result = _getRawUnicodeMap().get(codepoint); - if (!seen.contains(prop)) { - seen.add(prop); - System.out.println(prop); - } - if (DefaultValueType.forString(result) == DefaultValueType.CODE_POINT) { + return resolveValue(result, codepoint); + } + + private String resolveValue(String rawValue, int codepoint) { + if (DefaultValueType.forString(rawValue) == DefaultValueType.CODE_POINT) { return Character.toString(codepoint); - } else if (prop == UcdProperty.Name && result != null && result.endsWith("#")) { - return result.substring(0, result.length() - 1) + Utility.hex(codepoint); + } else if (prop == UcdProperty.Name && rawValue != null && result.endsWith("#")) { + return rawValue.substring(0, rawValue.length() - 1) + Utility.hex(codepoint); } else { - return result; + return rawValue; } } @@ -770,6 +770,4 @@ public UnicodeProperty getProperty(UcdProperty ucdProperty) { public UnicodeSet loadBinary(UcdProperty ucdProp) { return load(ucdProp).getSet(Binary.Yes.toString()); } - - static Set seen = new HashSet<>(); } From 739a6221acfc0e2db258074338bb80831ebb61b4 Mon Sep 17 00:00:00 2001 From: Robin Leroy Date: Fri, 2 Feb 2024 20:00:20 +0100 Subject: [PATCH 05/21] maybe try to make it compile too --- .../src/main/java/org/unicode/props/IndexUnicodeProperties.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java index 9377f4448..0ce8ca9c4 100644 --- a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java +++ b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java @@ -713,7 +713,7 @@ protected String _getValue(int codepoint) { private String resolveValue(String rawValue, int codepoint) { if (DefaultValueType.forString(rawValue) == DefaultValueType.CODE_POINT) { return Character.toString(codepoint); - } else if (prop == UcdProperty.Name && rawValue != null && result.endsWith("#")) { + } else if (prop == UcdProperty.Name && rawValue != null && rawValue.endsWith("#")) { return rawValue.substring(0, rawValue.length() - 1) + Utility.hex(codepoint); } else { return rawValue; From 4b4b03619f969f2741fb698bb08aa337f735cdcf Mon Sep 17 00:00:00 2001 From: Robin Leroy Date: Fri, 2 Feb 2024 20:40:36 +0100 Subject: [PATCH 06/21] strings --- .../main/java/org/unicode/props/IndexUnicodeProperties.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java index 0ce8ca9c4..ffe744ff9 100644 --- a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java +++ b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java @@ -28,7 +28,6 @@ import java.util.EnumMap; import java.util.EnumSet; import java.util.HashMap; -import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; @@ -685,7 +684,9 @@ protected UnicodeMap _getUnicodeMap() { || raw.containsValue("")) { UnicodeMap newMap = new UnicodeMap<>(); for (UnicodeMap.EntryRange range : raw.entryRanges()) { - if (DefaultValueType.forString(range.value) == DefaultValueType.CODE_POINT + if (range.codepoint == -1) { + newMap.put(range.string, range.value); + } else if (DefaultValueType.forString(range.value) == DefaultValueType.CODE_POINT || (prop == UcdProperty.Name && range.value.endsWith("#"))) { for (int c = range.codepoint; c <= range.codepointEnd; ++c) { newMap.put(c, resolveValue(range.value, c)); From f820fc44766d47afba63c1dba33182abd718f4ff Mon Sep 17 00:00:00 2001 From: Robin Leroy Date: Fri, 2 Feb 2024 23:09:40 +0100 Subject: [PATCH 07/21] spotless --- .../main/java/org/unicode/props/IndexUnicodeProperties.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java index ffe744ff9..27bc6f857 100644 --- a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java +++ b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java @@ -686,7 +686,8 @@ protected UnicodeMap _getUnicodeMap() { for (UnicodeMap.EntryRange range : raw.entryRanges()) { if (range.codepoint == -1) { newMap.put(range.string, range.value); - } else if (DefaultValueType.forString(range.value) == DefaultValueType.CODE_POINT + } else if (DefaultValueType.forString(range.value) + == DefaultValueType.CODE_POINT || (prop == UcdProperty.Name && range.value.endsWith("#"))) { for (int c = range.codepoint; c <= range.codepointEnd; ++c) { newMap.put(c, resolveValue(range.value, c)); From 0c615a853e1d86eb17ad1a555d6dc5021a21179a Mon Sep 17 00:00:00 2001 From: Robin Leroy Date: Sat, 3 Feb 2024 17:48:05 +0100 Subject: [PATCH 08/21] Some traces to see whether this is where we are spending time, and if so where we come from --- .../java/org/unicode/props/IndexUnicodeProperties.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java index 27bc6f857..f5d217cdb 100644 --- a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java +++ b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java @@ -682,6 +682,7 @@ protected UnicodeMap _getUnicodeMap() { if (prop == UcdProperty.Name || raw.containsValue("") || raw.containsValue("")) { + final long start = System.currentTimeMillis(); UnicodeMap newMap = new UnicodeMap<>(); for (UnicodeMap.EntryRange range : raw.entryRanges()) { if (range.codepoint == -1) { @@ -696,6 +697,13 @@ protected UnicodeMap _getUnicodeMap() { newMap.putAll(range.codepoint, range.codepointEnd, range.value); } } + final long stop = System.currentTimeMillis(); + final long Δt_in_ms = stop - start; + System.out.println("Built " + prop + " " + ucdVersion + " map in " + Δt_in_ms + " ms"); + if (Δt_in_ms > 500) { + new Throwable().printStackTrace(); + } + return newMap; } else { return raw; From e836f3c5d2ad140d6417cd908aab3da9aca3982e Mon Sep 17 00:00:00 2001 From: Robin Leroy Date: Sat, 3 Feb 2024 18:23:27 +0100 Subject: [PATCH 09/21] The map construction does not explain the sluggishness --- .../org/unicode/props/IndexUnicodeProperties.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java index f5d217cdb..b44e987b2 100644 --- a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java +++ b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java @@ -676,6 +676,19 @@ class IndexUnicodeProperty extends UnicodeProperty.BaseProperty { } } + @Override + public UnicodeSet getSet(PatternMatcher matcher, UnicodeSet result) { + final long start = System.currentTimeMillis(); + super.getSet(matcher, result); + final long stop = System.currentTimeMillis(); + final long Δt_in_ms = stop - start; + if (Δt_in_ms > 500) { + System.out.println("Long getSet for " + prop + " " + ucdVersion + " " + matcher + ": " + Δt_in_ms + " ms"); + new Throwable().printStackTrace(); + } + return result; + } + @Override protected UnicodeMap _getUnicodeMap() { var raw = _getRawUnicodeMap(); From 8db9d63bad7c1e231b015df4f5ae1c80a97a28e6 Mon Sep 17 00:00:00 2001 From: Robin Leroy Date: Sat, 3 Feb 2024 18:35:17 +0100 Subject: [PATCH 10/21] = --- .../src/main/java/org/unicode/props/IndexUnicodeProperties.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java index b44e987b2..2b07bfb48 100644 --- a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java +++ b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java @@ -679,7 +679,7 @@ class IndexUnicodeProperty extends UnicodeProperty.BaseProperty { @Override public UnicodeSet getSet(PatternMatcher matcher, UnicodeSet result) { final long start = System.currentTimeMillis(); - super.getSet(matcher, result); + result = super.getSet(matcher, result); final long stop = System.currentTimeMillis(); final long Δt_in_ms = stop - start; if (Δt_in_ms > 500) { From 3ae2ed27054ed3da697909cdbef5853b60a56a17 Mon Sep 17 00:00:00 2001 From: Robin Leroy Date: Sat, 3 Feb 2024 18:53:25 +0100 Subject: [PATCH 11/21] still not that... --- .../unicode/props/IndexUnicodeProperties.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java index 2b07bfb48..282e899f4 100644 --- a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java +++ b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java @@ -751,15 +751,25 @@ public List _getNameAliases(List result) { @Override protected List _getAvailableValues(List result) { + final long start = System.currentTimeMillis(); if (stringToNamedEnum != null) { result.addAll(enumValueNames); return result; + } else { + _getUnicodeMap().getAvailableValues(result); + } + final long stop = System.currentTimeMillis(); + final long Δt_in_ms = stop - start; + if (Δt_in_ms > 500) { + System.out.println("Long _getAvailableValues for " + prop + " " + ucdVersion + ": " + Δt_in_ms + " ms"); + new Throwable().printStackTrace(); } - return _getUnicodeMap().getAvailableValues(result); + return result; } @Override protected List _getValueAliases(String valueAlias, List result) { + final long start = System.currentTimeMillis(); if (stringToNamedEnum != null) { PropertyNames valueName = stringToNamedEnum.get(valueAlias); if (valueName != null) { @@ -771,6 +781,12 @@ protected List _getValueAliases(String valueAlias, List result) { result.add(valueAlias); } } + final long stop = System.currentTimeMillis(); + final long Δt_in_ms = stop - start; + if (Δt_in_ms > 500) { + System.out.println("Long _getValueAliases for " + prop + " " + ucdVersion + " " + valueAlias + ": " + Δt_in_ms + " ms"); + new Throwable().printStackTrace(); + } return result; } // @Override From 0982bc219314dbfa4eea6ead6594de4235ddd94a Mon Sep 17 00:00:00 2001 From: Robin Leroy Date: Sat, 3 Feb 2024 19:35:45 +0100 Subject: [PATCH 12/21] Revert "still not that..." This reverts commit 3ae2ed27054ed3da697909cdbef5853b60a56a17. --- .../unicode/props/IndexUnicodeProperties.java | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java index 282e899f4..2b07bfb48 100644 --- a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java +++ b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java @@ -751,25 +751,15 @@ public List _getNameAliases(List result) { @Override protected List _getAvailableValues(List result) { - final long start = System.currentTimeMillis(); if (stringToNamedEnum != null) { result.addAll(enumValueNames); return result; - } else { - _getUnicodeMap().getAvailableValues(result); - } - final long stop = System.currentTimeMillis(); - final long Δt_in_ms = stop - start; - if (Δt_in_ms > 500) { - System.out.println("Long _getAvailableValues for " + prop + " " + ucdVersion + ": " + Δt_in_ms + " ms"); - new Throwable().printStackTrace(); } - return result; + return _getUnicodeMap().getAvailableValues(result); } @Override protected List _getValueAliases(String valueAlias, List result) { - final long start = System.currentTimeMillis(); if (stringToNamedEnum != null) { PropertyNames valueName = stringToNamedEnum.get(valueAlias); if (valueName != null) { @@ -781,12 +771,6 @@ protected List _getValueAliases(String valueAlias, List result) { result.add(valueAlias); } } - final long stop = System.currentTimeMillis(); - final long Δt_in_ms = stop - start; - if (Δt_in_ms > 500) { - System.out.println("Long _getValueAliases for " + prop + " " + ucdVersion + " " + valueAlias + ": " + Δt_in_ms + " ms"); - new Throwable().printStackTrace(); - } return result; } // @Override From e61cde1db90d71d6583c6723628374ca4ada0a0d Mon Sep 17 00:00:00 2001 From: Robin Leroy Date: Sat, 3 Feb 2024 19:36:34 +0100 Subject: [PATCH 13/21] Do something obviously stupid and wrong in an attempt at figuring out where that time goes --- .../main/java/org/unicode/props/IndexUnicodeProperties.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java index 2b07bfb48..24fb38f8a 100644 --- a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java +++ b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java @@ -755,7 +755,7 @@ protected List _getAvailableValues(List result) { result.addAll(enumValueNames); return result; } - return _getUnicodeMap().getAvailableValues(result); + return _getRawUnicodeMap().getAvailableValues(result); } @Override @@ -767,7 +767,7 @@ protected List _getValueAliases(String valueAlias, List result) { } } if (!result.contains(valueAlias)) { - if (_getUnicodeMap().containsValue(valueAlias)) { + if (_getRawUnicodeMap().containsValue(valueAlias)) { result.add(valueAlias); } } From e1733363efb8eacc961d0e946f55a6298505ce4e Mon Sep 17 00:00:00 2001 From: Robin Leroy Date: Sun, 4 Feb 2024 01:18:56 +0100 Subject: [PATCH 14/21] #$%@#$^#&% --- .../unicode/props/IndexUnicodeProperties.java | 31 +------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java index 24fb38f8a..57c47d0a9 100644 --- a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java +++ b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java @@ -691,36 +691,7 @@ public UnicodeSet getSet(PatternMatcher matcher, UnicodeSet result) { @Override protected UnicodeMap _getUnicodeMap() { - var raw = _getRawUnicodeMap(); - if (prop == UcdProperty.Name - || raw.containsValue("") - || raw.containsValue("")) { - final long start = System.currentTimeMillis(); - UnicodeMap newMap = new UnicodeMap<>(); - for (UnicodeMap.EntryRange range : raw.entryRanges()) { - if (range.codepoint == -1) { - newMap.put(range.string, range.value); - } else if (DefaultValueType.forString(range.value) - == DefaultValueType.CODE_POINT - || (prop == UcdProperty.Name && range.value.endsWith("#"))) { - for (int c = range.codepoint; c <= range.codepointEnd; ++c) { - newMap.put(c, resolveValue(range.value, c)); - } - } else { - newMap.putAll(range.codepoint, range.codepointEnd, range.value); - } - } - final long stop = System.currentTimeMillis(); - final long Δt_in_ms = stop - start; - System.out.println("Built " + prop + " " + ucdVersion + " map in " + Δt_in_ms + " ms"); - if (Δt_in_ms > 500) { - new Throwable().printStackTrace(); - } - - return newMap; - } else { - return raw; - } + return _getRawUnicodeMap(); } protected UnicodeMap _getRawUnicodeMap() { From 6d64e7146eaf56482a3f0fec844af68aaf3509b9 Mon Sep 17 00:00:00 2001 From: Robin Leroy Date: Mon, 5 Feb 2024 13:56:03 +0100 Subject: [PATCH 15/21] More eggsperiments --- .../unicode/props/IndexUnicodeProperties.java | 33 +++++++++++++++++-- .../org/unicode/props/UnicodeProperty.java | 7 +++- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java index 57c47d0a9..9e17f47c0 100644 --- a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java +++ b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java @@ -679,7 +679,7 @@ class IndexUnicodeProperty extends UnicodeProperty.BaseProperty { @Override public UnicodeSet getSet(PatternMatcher matcher, UnicodeSet result) { final long start = System.currentTimeMillis(); - result = super.getSet(matcher, result); + result = getSet(matcher, result, () -> _getRawUnicodeMap()); final long stop = System.currentTimeMillis(); final long Δt_in_ms = stop - start; if (Δt_in_ms > 500) { @@ -691,7 +691,36 @@ public UnicodeSet getSet(PatternMatcher matcher, UnicodeSet result) { @Override protected UnicodeMap _getUnicodeMap() { - return _getRawUnicodeMap(); + var raw = _getRawUnicodeMap(); + if (prop == UcdProperty.Name + || raw.containsValue("") + || raw.containsValue("")) { + final long start = System.currentTimeMillis(); + UnicodeMap newMap = new UnicodeMap<>(); + for (UnicodeMap.EntryRange range : raw.entryRanges()) { + if (range.codepoint == -1) { + newMap.put(range.string, range.value); + } else if (DefaultValueType.forString(range.value) + == DefaultValueType.CODE_POINT + || (prop == UcdProperty.Name && range.value.endsWith("#"))) { + for (int c = range.codepoint; c <= range.codepointEnd; ++c) { + newMap.put(c, resolveValue(range.value, c)); + } + } else { + newMap.putAll(range.codepoint, range.codepointEnd, range.value); + } + } + final long stop = System.currentTimeMillis(); + final long Δt_in_ms = stop - start; + System.out.println("Built " + prop + " " + ucdVersion + " map in " + Δt_in_ms + " ms"); + if (Δt_in_ms > 500) { + new Throwable().printStackTrace(); + } + + return newMap; + } else { + return raw; + } } protected UnicodeMap _getRawUnicodeMap() { diff --git a/unicodetools/src/main/java/org/unicode/props/UnicodeProperty.java b/unicodetools/src/main/java/org/unicode/props/UnicodeProperty.java index 016643106..4cfd4c2b3 100644 --- a/unicodetools/src/main/java/org/unicode/props/UnicodeProperty.java +++ b/unicodetools/src/main/java/org/unicode/props/UnicodeProperty.java @@ -30,6 +30,7 @@ import java.util.Set; import java.util.TreeMap; import java.util.function.Predicate; +import java.util.function.Supplier; import java.util.regex.Pattern; import org.unicode.cldr.util.props.UnicodeLabel; @@ -443,6 +444,10 @@ public final UnicodeSet getSet(String propertyValue, UnicodeSet result) { public static final String UNUSED = "??"; public UnicodeSet getSet(PatternMatcher matcher, UnicodeSet result) { + return getSet(matcher, result, () -> getUnicodeMap_internal()); + } + + protected final UnicodeSet getSet(PatternMatcher matcher, UnicodeSet result, Supplier> unicodeMap) { if (result == null) result = new UnicodeSet(); boolean uniformUnassigned = hasUniformUnassigned(); if (isType(STRING_OR_MISC_MASK) && !isMultivalued) { @@ -458,7 +463,7 @@ public UnicodeSet getSet(PatternMatcher matcher, UnicodeSet result) { } List valueAliases = new ArrayList<>(1); // to avoid reallocating... List partAliases = new ArrayList<>(1); - UnicodeMap um = getUnicodeMap_internal(); + UnicodeMap um = unicodeMap.get(); Iterator it = um.getAvailableValues(null).iterator(); main: while (it.hasNext()) { From 4d7a2bf03fa57a167d9a2dd2915a237f927026c6 Mon Sep 17 00:00:00 2001 From: Robin Leroy Date: Mon, 5 Feb 2024 14:31:59 +0100 Subject: [PATCH 16/21] Try more things --- .../main/java/org/unicode/props/IndexUnicodeProperties.java | 4 +--- .../main/java/org/unicode/text/UCD/VersionedProperty.java | 5 +---- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java index 9e17f47c0..699d5a659 100644 --- a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java +++ b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java @@ -713,9 +713,7 @@ protected UnicodeMap _getUnicodeMap() { final long stop = System.currentTimeMillis(); final long Δt_in_ms = stop - start; System.out.println("Built " + prop + " " + ucdVersion + " map in " + Δt_in_ms + " ms"); - if (Δt_in_ms > 500) { - new Throwable().printStackTrace(); - } + new Throwable().printStackTrace(System.out); return newMap; } else { diff --git a/unicodetools/src/main/java/org/unicode/text/UCD/VersionedProperty.java b/unicodetools/src/main/java/org/unicode/text/UCD/VersionedProperty.java index f3f068dbf..67dce326e 100644 --- a/unicodetools/src/main/java/org/unicode/text/UCD/VersionedProperty.java +++ b/unicodetools/src/main/java/org/unicode/text/UCD/VersionedProperty.java @@ -64,10 +64,7 @@ public static VersionedProperty forJSPs() { Set.of("toNFC", "toNFD", "toNFKC", "toNFKD"); private static boolean isTrivial(UnicodeMap map) { - return map.isEmpty() - || (map.values().size() == 1 - && map.getSet(map.values().iterator().next()) - .equals(UnicodeSet.ALL_CODE_POINTS)); + return map.isEmpty() || map.getSet("").equals(UnicodeSet.ALL_CODE_POINTS); } public UnicodeProperty getProperty() { From b05ca4a1dc234c26d5d2c191909d534965b2ffd2 Mon Sep 17 00:00:00 2001 From: Robin Leroy Date: Mon, 5 Feb 2024 15:10:37 +0100 Subject: [PATCH 17/21] isTrivial --- .../main/java/org/unicode/props/IndexUnicodeProperties.java | 5 +++++ .../src/main/java/org/unicode/props/UnicodeProperty.java | 5 +++++ .../main/java/org/unicode/text/UCD/VersionedProperty.java | 4 ++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java index 699d5a659..e3e668921 100644 --- a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java +++ b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java @@ -689,6 +689,11 @@ public UnicodeSet getSet(PatternMatcher matcher, UnicodeSet result) { return result; } + @Override + public boolean isTrivial() { + return _getRawUnicodeMap().isEmpty() || _getRawUnicodeMap().keySet("").equals(UnicodeSet.ALL_CODE_POINTS); + } + @Override protected UnicodeMap _getUnicodeMap() { var raw = _getRawUnicodeMap(); diff --git a/unicodetools/src/main/java/org/unicode/props/UnicodeProperty.java b/unicodetools/src/main/java/org/unicode/props/UnicodeProperty.java index 4cfd4c2b3..188f8e70c 100644 --- a/unicodetools/src/main/java/org/unicode/props/UnicodeProperty.java +++ b/unicodetools/src/main/java/org/unicode/props/UnicodeProperty.java @@ -555,6 +555,11 @@ public UnicodeMap getUnicodeMap() { return getUnicodeMap(false); } + public boolean isTrivial() { + final var map = getUnicodeMap(); + return map.isEmpty() || map.keySet("").equals(UnicodeSet.ALL_CODE_POINTS) && map.stringKeys().isEmpty(); + } + /** * @return the unicode map */ diff --git a/unicodetools/src/main/java/org/unicode/text/UCD/VersionedProperty.java b/unicodetools/src/main/java/org/unicode/text/UCD/VersionedProperty.java index 67dce326e..5c7c00e7b 100644 --- a/unicodetools/src/main/java/org/unicode/text/UCD/VersionedProperty.java +++ b/unicodetools/src/main/java/org/unicode/text/UCD/VersionedProperty.java @@ -109,11 +109,11 @@ public VersionedProperty set(String xPropertyName) { propSource = getIndexedProperties(version); property = propSource.getProperty(xPropertyName); if ((property == null && TOOL_ONLY_PROPERTIES.contains(xPropertyName)) - || (property != null && isTrivial(property.getUnicodeMap()) && allowRetroactive)) { + || (property != null && property.isTrivial() && allowRetroactive)) { propSource = ToolUnicodePropertySource.make(version); property = propSource.getProperty(xPropertyName); } - if (property == null || isTrivial(property.getUnicodeMap())) { + if (property == null || property.isTrivial()) { if (!throwOnUnknownProperty) { return null; } From ee95c8c2103032bf051cd212c57d96e57913afed Mon Sep 17 00:00:00 2001 From: Robin Leroy Date: Mon, 5 Feb 2024 15:11:02 +0100 Subject: [PATCH 18/21] unused --- .../src/main/java/org/unicode/text/UCD/VersionedProperty.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/unicodetools/src/main/java/org/unicode/text/UCD/VersionedProperty.java b/unicodetools/src/main/java/org/unicode/text/UCD/VersionedProperty.java index 5c7c00e7b..d9fd19216 100644 --- a/unicodetools/src/main/java/org/unicode/text/UCD/VersionedProperty.java +++ b/unicodetools/src/main/java/org/unicode/text/UCD/VersionedProperty.java @@ -63,10 +63,6 @@ public static VersionedProperty forJSPs() { private static final Set TOOL_ONLY_PROPERTIES = Set.of("toNFC", "toNFD", "toNFKC", "toNFKD"); - private static boolean isTrivial(UnicodeMap map) { - return map.isEmpty() || map.getSet("").equals(UnicodeSet.ALL_CODE_POINTS); - } - public UnicodeProperty getProperty() { return property; } From 9fab320f678dfdfc49d36f20398006c215a1ee90 Mon Sep 17 00:00:00 2001 From: Robin Leroy Date: Mon, 5 Feb 2024 15:27:39 +0100 Subject: [PATCH 19/21] Can we do something correct too? --- .../unicode/props/IndexUnicodeProperties.java | 18 +++--------------- .../org/unicode/props/UnicodeProperty.java | 6 +----- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java index e3e668921..a8452139d 100644 --- a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java +++ b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java @@ -676,19 +676,6 @@ class IndexUnicodeProperty extends UnicodeProperty.BaseProperty { } } - @Override - public UnicodeSet getSet(PatternMatcher matcher, UnicodeSet result) { - final long start = System.currentTimeMillis(); - result = getSet(matcher, result, () -> _getRawUnicodeMap()); - final long stop = System.currentTimeMillis(); - final long Δt_in_ms = stop - start; - if (Δt_in_ms > 500) { - System.out.println("Long getSet for " + prop + " " + ucdVersion + " " + matcher + ": " + Δt_in_ms + " ms"); - new Throwable().printStackTrace(); - } - return result; - } - @Override public boolean isTrivial() { return _getRawUnicodeMap().isEmpty() || _getRawUnicodeMap().keySet("").equals(UnicodeSet.ALL_CODE_POINTS); @@ -758,7 +745,7 @@ protected List _getAvailableValues(List result) { result.addAll(enumValueNames); return result; } - return _getRawUnicodeMap().getAvailableValues(result); + return _getUnicodeMap().getAvailableValues(result); } @Override @@ -770,7 +757,8 @@ protected List _getValueAliases(String valueAlias, List result) { } } if (!result.contains(valueAlias)) { - if (_getRawUnicodeMap().containsValue(valueAlias)) { + // TODO(egg): We should not be constructing this map for this. + if (_getUnicodeMap().containsValue(valueAlias)) { result.add(valueAlias); } } diff --git a/unicodetools/src/main/java/org/unicode/props/UnicodeProperty.java b/unicodetools/src/main/java/org/unicode/props/UnicodeProperty.java index 188f8e70c..396228fce 100644 --- a/unicodetools/src/main/java/org/unicode/props/UnicodeProperty.java +++ b/unicodetools/src/main/java/org/unicode/props/UnicodeProperty.java @@ -444,10 +444,6 @@ public final UnicodeSet getSet(String propertyValue, UnicodeSet result) { public static final String UNUSED = "??"; public UnicodeSet getSet(PatternMatcher matcher, UnicodeSet result) { - return getSet(matcher, result, () -> getUnicodeMap_internal()); - } - - protected final UnicodeSet getSet(PatternMatcher matcher, UnicodeSet result, Supplier> unicodeMap) { if (result == null) result = new UnicodeSet(); boolean uniformUnassigned = hasUniformUnassigned(); if (isType(STRING_OR_MISC_MASK) && !isMultivalued) { @@ -463,7 +459,7 @@ protected final UnicodeSet getSet(PatternMatcher matcher, UnicodeSet result, Sup } List valueAliases = new ArrayList<>(1); // to avoid reallocating... List partAliases = new ArrayList<>(1); - UnicodeMap um = unicodeMap.get(); + UnicodeMap um = getUnicodeMap_internal(); Iterator it = um.getAvailableValues(null).iterator(); main: while (it.hasNext()) { From d2cde5961fb7c44e775991b6f29aa0d91434a8c5 Mon Sep 17 00:00:00 2001 From: Robin Leroy Date: Mon, 5 Feb 2024 15:40:50 +0100 Subject: [PATCH 20/21] spotless --- .../main/java/org/unicode/props/IndexUnicodeProperties.java | 6 ++++-- .../src/main/java/org/unicode/props/UnicodeProperty.java | 4 ++-- .../main/java/org/unicode/text/UCD/VersionedProperty.java | 1 - 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java index a8452139d..9ade18691 100644 --- a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java +++ b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java @@ -678,7 +678,8 @@ class IndexUnicodeProperty extends UnicodeProperty.BaseProperty { @Override public boolean isTrivial() { - return _getRawUnicodeMap().isEmpty() || _getRawUnicodeMap().keySet("").equals(UnicodeSet.ALL_CODE_POINTS); + return _getRawUnicodeMap().isEmpty() + || _getRawUnicodeMap().keySet("").equals(UnicodeSet.ALL_CODE_POINTS); } @Override @@ -704,7 +705,8 @@ protected UnicodeMap _getUnicodeMap() { } final long stop = System.currentTimeMillis(); final long Δt_in_ms = stop - start; - System.out.println("Built " + prop + " " + ucdVersion + " map in " + Δt_in_ms + " ms"); + System.out.println( + "Built " + prop + " " + ucdVersion + " map in " + Δt_in_ms + " ms"); new Throwable().printStackTrace(System.out); return newMap; diff --git a/unicodetools/src/main/java/org/unicode/props/UnicodeProperty.java b/unicodetools/src/main/java/org/unicode/props/UnicodeProperty.java index 396228fce..3b52f7e9e 100644 --- a/unicodetools/src/main/java/org/unicode/props/UnicodeProperty.java +++ b/unicodetools/src/main/java/org/unicode/props/UnicodeProperty.java @@ -30,7 +30,6 @@ import java.util.Set; import java.util.TreeMap; import java.util.function.Predicate; -import java.util.function.Supplier; import java.util.regex.Pattern; import org.unicode.cldr.util.props.UnicodeLabel; @@ -553,7 +552,8 @@ public UnicodeMap getUnicodeMap() { public boolean isTrivial() { final var map = getUnicodeMap(); - return map.isEmpty() || map.keySet("").equals(UnicodeSet.ALL_CODE_POINTS) && map.stringKeys().isEmpty(); + return map.isEmpty() + || map.keySet("").equals(UnicodeSet.ALL_CODE_POINTS) && map.stringKeys().isEmpty(); } /** diff --git a/unicodetools/src/main/java/org/unicode/text/UCD/VersionedProperty.java b/unicodetools/src/main/java/org/unicode/text/UCD/VersionedProperty.java index d9fd19216..6599681fb 100644 --- a/unicodetools/src/main/java/org/unicode/text/UCD/VersionedProperty.java +++ b/unicodetools/src/main/java/org/unicode/text/UCD/VersionedProperty.java @@ -1,6 +1,5 @@ package org.unicode.text.UCD; -import com.ibm.icu.dev.util.UnicodeMap; import com.ibm.icu.text.SymbolTable; import com.ibm.icu.text.UnicodeSet; import java.text.ParsePosition; From e3c13d4e728f1cd367f7403ed3670e5db385c72b Mon Sep 17 00:00:00 2001 From: Robin Leroy Date: Mon, 5 Feb 2024 15:59:31 +0100 Subject: [PATCH 21/21] Document the trace --- .../main/java/org/unicode/props/IndexUnicodeProperties.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java index 9ade18691..2aafc819f 100644 --- a/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java +++ b/unicodetools/src/main/java/org/unicode/props/IndexUnicodeProperties.java @@ -705,6 +705,10 @@ protected UnicodeMap _getUnicodeMap() { } final long stop = System.currentTimeMillis(); final long Δt_in_ms = stop - start; + // We do not want to construct these UnicodeMaps that map most of the code space to + // itself, not so much because building them is costly, but because whatever we do + // on them is almost certainly a bad idea (for instance calling `values()` will be + // extremely slow). Log a trace so we can figure out where we are using this. System.out.println( "Built " + prop + " " + ucdVersion + " map in " + Δt_in_ms + " ms"); new Throwable().printStackTrace(System.out);