diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 168a201c388..cd378a889d2 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1394,14 +1394,18 @@ namespace ts { } } - export function copyListRemovingItem(item: T, list: T[]) { - const copiedList: T[] = []; - for (const e of list) { - if (e !== item) { - copiedList.push(e); + export function removeItem(item: T, array: T[]): void { + for (let i = 0; i < array.length; i++) { + if (array[i] === item) { + // Move everything over to the left. + // This seems to be faster than either `array.splice(i, 1)` or `array.copyWithin(i, i+ 1)`. + for (; i < array.length - 1; i++) { + array[i] = array[i + 1]; + } + array.pop(); + break; } } - return copiedList; } export function createGetCanonicalFileName(useCaseSensitivefileNames: boolean): (fileName: string) => string { diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index 350d75429b7..7953a2f42e8 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -285,13 +285,10 @@ namespace ts { function removeFileWatcherCallback(filePath: string, callback: FileWatcherCallback) { const callbacks = fileWatcherCallbacks[filePath]; if (callbacks) { - const newCallbacks = copyListRemovingItem(callback, callbacks); - if (newCallbacks.length === 0) { + removeItem(callback, callbacks); + if (callbacks.length === 0) { delete fileWatcherCallbacks[filePath]; } - else { - fileWatcherCallbacks[filePath] = newCallbacks; - } } } diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index a14c42f471e..0a12bf68d79 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -275,7 +275,7 @@ namespace ts.server { removeRoot(info: ScriptInfo) { if (this.filenameToScript.contains(info.path)) { this.filenameToScript.remove(info.path); - this.roots = copyListRemovingItem(info, this.roots); + removeItem(info, this.roots); this.resolvedModuleNames.remove(info.path); this.resolvedTypeReferenceDirectives.remove(info.path); } @@ -585,16 +585,6 @@ namespace ts.server { project?: Project; } - function copyListRemovingItem(item: T, list: T[]) { - const copiedList: T[] = []; - for (let i = 0, len = list.length; i < len; i++) { - if (list[i] != item) { - copiedList.push(list[i]); - } - } - return copiedList; - } - /** * This helper funciton processes a list of projects and return the concatenated, sortd and deduplicated output of processing each project. */ @@ -859,7 +849,7 @@ namespace ts.server { project.directoryWatcher.close(); forEachValue(project.directoriesWatchedForWildcards, watcher => { watcher.close(); }); delete project.directoriesWatchedForWildcards; - this.configuredProjects = copyListRemovingItem(project, this.configuredProjects); + removeItem(project, this.configuredProjects); } else { for (const directory of project.directoriesWatchedForTsconfig) { @@ -871,7 +861,7 @@ namespace ts.server { delete project.projectService.directoryWatchersForTsconfig[directory]; } } - this.inferredProjects = copyListRemovingItem(project, this.inferredProjects); + removeItem(project, this.inferredProjects); } const fileNames = project.getFileNames(); @@ -996,7 +986,7 @@ namespace ts.server { } } else { - this.openFilesReferenced = copyListRemovingItem(info, this.openFilesReferenced); + removeItem(info, this.openFilesReferenced); } info.close(); } @@ -1506,13 +1496,13 @@ namespace ts.server { // openFileRoots or openFileReferenced. if (info.isOpen) { if (this.openFileRoots.indexOf(info) >= 0) { - this.openFileRoots = copyListRemovingItem(info, this.openFileRoots); + removeItem(info, this.openFileRoots); if (info.defaultProject && !info.defaultProject.isConfiguredProject()) { this.removeProject(info.defaultProject); } } if (this.openFilesReferenced.indexOf(info) >= 0) { - this.openFilesReferenced = copyListRemovingItem(info, this.openFilesReferenced); + removeItem(info, this.openFilesReferenced); } this.openFileRootsConfigured.push(info); info.defaultProject = project; diff --git a/src/server/server.ts b/src/server/server.ts index 17ecfdaa1c9..b0f852b14f1 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -204,7 +204,7 @@ namespace ts.server { // average async stat takes about 30 microseconds // set chunk size to do 30 files in < 1 millisecond function createPollingWatchedFileSet(interval = 2500, chunkSize = 30) { - let watchedFiles: WatchedFile[] = []; + const watchedFiles: WatchedFile[] = []; let nextFileToCheck = 0; let watchTimer: any; @@ -267,7 +267,7 @@ namespace ts.server { } function removeFile(file: WatchedFile) { - watchedFiles = copyListRemovingItem(file, watchedFiles); + removeItem(file, watchedFiles); } return {