On 9 Mar 2016, at 14:43, Peter Levart <peter.lev...@gmail.com> wrote:
> > On 03/09/2016 02:44 PM, Chris Hegarty wrote: >> On 9 Mar 2016, at 13:03, Claes Redestad <claes.redes...@oracle.com> wrote: >> >>> On 2016-03-09 13:17, Peter Levart wrote: >>>>> When digging through old history to try to find out why >>>>> java.util.jar.Attributes >>>>> was ever using ASCIICaseInsensitiveComparator, it was not clear that >>>>> performance was the motivation. >>>> I guess looking-up a manifest attribute is not a performance critical >>>> operation, you are right. >>> Could this be an old startup optimization, since first call to >>> String.toLowerCase/toUpperCase will initialize and pull in java.util.Locale >>> and friends? If so it's probably not effective any more. >>> >>> Coincidentally - due to a recent regression - we're currently spending >>> quite a bit of time parsing manifests of all jar files on the classpath, >>> making ASCIICaseInsensitiveComparator show up prominently in some startup >>> profiles. >> Not any more ( it is no longer with us )!! >> >> Interesting… let me know if you issues once this change makes its >> way into a promoted build, or during your performance investigations. >> >> BTW. I am not against doing something “smarter” for Attributes.hashCode. >> I just didn’t think it was relevant, or performance sensitive, any more. >> >> -Chris > > Hi Chris, > > I have another concern. Let's say Attributes keys are LATIN1. So for > comparison, the StringLatin1.compareToCI is used: > > public static int compareToCI(byte[] value, byte[] other) { > int len1 = value.length; > int len2 = other.length; > int lim = Math.min(len1, len2); > for (int k = 0; k < lim; k++) { > if (value[k] != other[k]) { > char c1 = (char) > CharacterDataLatin1.instance.toUpperCase(getChar(value, k)); > char c2 = (char) > CharacterDataLatin1.instance.toUpperCase(getChar(other, k)); > if (c1 != c2) { > c1 = (char) CharacterDataLatin1.instance.toLowerCase(c1); > c2 = (char) CharacterDataLatin1.instance.toLowerCase(c2); > if (c1 != c2) { > return c1 - c2; > } > } > } > } > return len1 - len2; > } > > comparing this with Name.hashCode: > > public int hashCode() { > if (hashCode == -1) { > hashCode = name.toLowerCase(Locale.ROOT).hashCode(); > } > return hashCode; > } > > > ...is it possible that for some pair of keys, compareToCI would result in 0, > but hashCode(s) would differ? For example, the uppercased keys would be the > same, but the .toLowerCase(Locale.ROOT) not? Maybe not for LATIN1 keys, but > what if one uses non-latin1 keys (StringUTF16.compareToCI is similar)? Can this really happen? ASCIICaseInsensitiveComparator was asserting that string characters were ASCII, so this situation would have triggered an assert with the old code, no? -Chris.