Use collator when making comparison as it is more performance than String.prototype.localeCompare

This commit is contained in:
Yui T
2016-10-17 09:12:08 -07:00
parent 65b1cf665e
commit 2bb4abce47
2 changed files with 10 additions and 25 deletions
+9 -4
View File
@@ -21,7 +21,9 @@ namespace ts {
const createObject = Object.create;
// More efficient to create a collator once and use its `compare` than to call `a.localeCompare(b)` many times.
export const collator: { compare(a: string, b: string): number } = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator() : undefined;
export const collator: { compare(a: string, b: string): number } = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(/*locales*/ undefined, { usage: "sort", sensitivity: "accent" }) : undefined;
// Intl is missing in Safari, and node 0.10 treats "a" as greater than "B".
export const localeCompareIsCorrect = ts.collator && ts.collator.compare("a", "B") < 0;
export function createMap<T>(template?: MapLike<T>): Map<T> {
const map: Map<T> = createObject(null); // tslint:disable-line:no-null-keyword
@@ -1050,9 +1052,12 @@ namespace ts {
if (a === undefined) return Comparison.LessThan;
if (b === undefined) return Comparison.GreaterThan;
if (ignoreCase) {
if (collator && String.prototype.localeCompare) {
// accent means a ≠ b, a ≠ á, a = A
const result = a.localeCompare(b, /*locales*/ undefined, { usage: "sort", sensitivity: "accent" });
// Checking if "collator exists indicates that Intl is available.
// We still have to check if "collator.compare" is correct. If it is not, use "String.localeComapre"
if (collator) {
const result = localeCompareIsCorrect ?
collator.compare(a, b) :
a.localeCompare(b, /*locales*/ undefined, { usage: "sort", sensitivity: "accent" }); // accent means a ≠ b, a ≠ á, a = A
return result < 0 ? Comparison.LessThan : result > 0 ? Comparison.GreaterThan : Comparison.EqualTo;
}
+1 -21
View File
@@ -322,7 +322,7 @@ namespace ts.NavigationBar {
function compareChildren(child1: NavigationBarNode, child2: NavigationBarNode): number {
const name1 = tryGetName(child1.node), name2 = tryGetName(child2.node);
if (name1 && name2) {
const cmp = localeCompareFix(name1, name2);
const cmp = ts.compareStringsCaseInsensitive(name1, name2);
return cmp !== 0 ? cmp : navigationBarNodeKind(child1) - navigationBarNodeKind(child2);
}
else {
@@ -330,26 +330,6 @@ namespace ts.NavigationBar {
}
}
// Intl is missing in Safari, and node 0.10 treats "a" as greater than "B".
const localeCompareIsCorrect = ts.collator && ts.collator.compare("a", "B") < 0;
const localeCompareFix: (a: string, b: string) => number = localeCompareIsCorrect ? collator.compare : function(a, b) {
// This isn't perfect, but it passes all of our tests.
for (let i = 0; i < Math.min(a.length, b.length); i++) {
const chA = a.charAt(i), chB = b.charAt(i);
if (chA === "\"" && chB === "'") {
return 1;
}
if (chA === "'" && chB === "\"") {
return -1;
}
const cmp = ts.compareStrings(chA.toLocaleLowerCase(), chB.toLocaleLowerCase());
if (cmp !== 0) {
return cmp;
}
}
return a.length - b.length;
};
/**
* This differs from getItemName because this is just used for sorting.
* We only sort nodes by name that have a more-or-less "direct" name, as opposed to `new()` and the like.