perf(ngcc): use line start positions for computing offsets in source-map flattening (#36027)
By computing and caching the start of each line, rather than the length of each line, we can save a lot of duplicated computation in the `segmentDiff()` and `offsetSegment()` functions. PR Close #36027
This commit is contained in:

committed by
Andrew Kushnir

parent
a40be00e17
commit
e8900824dd
@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {compareSegments, offsetSegment, segmentDiff} from '../../src/sourcemaps/segment_marker';
|
||||
import {computeLineLengths} from '../../src/sourcemaps/source_file';
|
||||
import {computeStartOfLinePositions} from '../../src/sourcemaps/source_file';
|
||||
|
||||
describe('SegmentMarker utils', () => {
|
||||
describe('compareSegments()', () => {
|
||||
@ -34,77 +34,99 @@ describe('SegmentMarker utils', () => {
|
||||
|
||||
describe('segmentDiff()', () => {
|
||||
it('should return 0 if the segments are the same', () => {
|
||||
const lineLengths = computeLineLengths('abcdef\nabcdefghj\nabcdefghijklm\nabcdef');
|
||||
expect(segmentDiff(lineLengths, {line: 0, column: 0}, {line: 0, column: 0})).toEqual(0);
|
||||
expect(segmentDiff(lineLengths, {line: 3, column: 0}, {line: 3, column: 0})).toEqual(0);
|
||||
expect(segmentDiff(lineLengths, {line: 0, column: 5}, {line: 0, column: 5})).toEqual(0);
|
||||
expect(segmentDiff(lineLengths, {line: 3, column: 5}, {line: 3, column: 5})).toEqual(0);
|
||||
const startOfLinePositions =
|
||||
computeStartOfLinePositions('abcdef\nabcdefghj\nabcdefghijklm\nabcdef');
|
||||
expect(segmentDiff(startOfLinePositions, {line: 0, column: 0}, {line: 0, column: 0}))
|
||||
.toEqual(0);
|
||||
expect(segmentDiff(startOfLinePositions, {line: 3, column: 0}, {line: 3, column: 0}))
|
||||
.toEqual(0);
|
||||
expect(segmentDiff(startOfLinePositions, {line: 0, column: 5}, {line: 0, column: 5}))
|
||||
.toEqual(0);
|
||||
expect(segmentDiff(startOfLinePositions, {line: 3, column: 5}, {line: 3, column: 5}))
|
||||
.toEqual(0);
|
||||
});
|
||||
|
||||
it('should return the column difference if the markers are on the same line', () => {
|
||||
const lineLengths = computeLineLengths('abcdef\nabcdefghj\nabcdefghijklm\nabcdef');
|
||||
expect(segmentDiff(lineLengths, {line: 0, column: 0}, {line: 0, column: 3})).toEqual(3);
|
||||
expect(segmentDiff(lineLengths, {line: 1, column: 1}, {line: 1, column: 5})).toEqual(4);
|
||||
expect(segmentDiff(lineLengths, {line: 2, column: 5}, {line: 2, column: 1})).toEqual(-4);
|
||||
expect(segmentDiff(lineLengths, {line: 3, column: 3}, {line: 3, column: 0})).toEqual(-3);
|
||||
const startOfLinePositions =
|
||||
computeStartOfLinePositions('abcdef\nabcdefghj\nabcdefghijklm\nabcdef');
|
||||
expect(segmentDiff(startOfLinePositions, {line: 0, column: 0}, {line: 0, column: 3}))
|
||||
.toEqual(3);
|
||||
expect(segmentDiff(startOfLinePositions, {line: 1, column: 1}, {line: 1, column: 5}))
|
||||
.toEqual(4);
|
||||
expect(segmentDiff(startOfLinePositions, {line: 2, column: 5}, {line: 2, column: 1}))
|
||||
.toEqual(-4);
|
||||
expect(segmentDiff(startOfLinePositions, {line: 3, column: 3}, {line: 3, column: 0}))
|
||||
.toEqual(-3);
|
||||
});
|
||||
|
||||
it('should return the number of actual characters difference (including newlineLengths) if not on the same line',
|
||||
it('should return the number of actual characters difference (including newline markers) if not on the same line',
|
||||
() => {
|
||||
let lineLengths: number[];
|
||||
let startOfLinePositions: number[];
|
||||
|
||||
lineLengths = computeLineLengths('A12345\nB123456789');
|
||||
expect(segmentDiff(lineLengths, {line: 0, column: 0}, {line: 1, column: 0}))
|
||||
startOfLinePositions = computeStartOfLinePositions('A12345\nB123456789');
|
||||
expect(segmentDiff(startOfLinePositions, {line: 0, column: 0}, {line: 1, column: 0}))
|
||||
.toEqual(6 + 1);
|
||||
|
||||
lineLengths = computeLineLengths('012A45\n01234B6789');
|
||||
expect(segmentDiff(lineLengths, {line: 0, column: 3}, {line: 1, column: 5}))
|
||||
startOfLinePositions = computeStartOfLinePositions('012A45\n01234B6789');
|
||||
expect(segmentDiff(startOfLinePositions, {line: 0, column: 3}, {line: 1, column: 5}))
|
||||
.toEqual(3 + 1 + 5);
|
||||
|
||||
lineLengths = computeLineLengths('012345\n012345A789\n01234567\nB123456');
|
||||
expect(segmentDiff(lineLengths, {line: 1, column: 6}, {line: 3, column: 0}))
|
||||
startOfLinePositions =
|
||||
computeStartOfLinePositions('012345\n012345A789\n01234567\nB123456');
|
||||
expect(segmentDiff(startOfLinePositions, {line: 1, column: 6}, {line: 3, column: 0}))
|
||||
.toEqual(4 + 1 + 8 + 1 + 0);
|
||||
|
||||
lineLengths = computeLineLengths('012345\nA123456789\n01234567\n012B456');
|
||||
expect(segmentDiff(lineLengths, {line: 1, column: 0}, {line: 3, column: 3}))
|
||||
startOfLinePositions =
|
||||
computeStartOfLinePositions('012345\nA123456789\n01234567\n012B456');
|
||||
expect(segmentDiff(startOfLinePositions, {line: 1, column: 0}, {line: 3, column: 3}))
|
||||
.toEqual(10 + 1 + 8 + 1 + 3);
|
||||
|
||||
lineLengths = computeLineLengths('012345\nB123456789\nA1234567\n0123456');
|
||||
expect(segmentDiff(lineLengths, {line: 2, column: 0}, {line: 1, column: 0}))
|
||||
startOfLinePositions =
|
||||
computeStartOfLinePositions('012345\nB123456789\nA1234567\n0123456');
|
||||
expect(segmentDiff(startOfLinePositions, {line: 2, column: 0}, {line: 1, column: 0}))
|
||||
.toEqual(0 - 1 - 10 + 0);
|
||||
|
||||
lineLengths = computeLineLengths('012345\n0123B56789\n01234567\n012A456');
|
||||
expect(segmentDiff(lineLengths, {line: 3, column: 3}, {line: 1, column: 4}))
|
||||
startOfLinePositions =
|
||||
computeStartOfLinePositions('012345\n0123B56789\n01234567\n012A456');
|
||||
expect(segmentDiff(startOfLinePositions, {line: 3, column: 3}, {line: 1, column: 4}))
|
||||
.toEqual(-3 - 1 - 8 - 1 - 10 + 4);
|
||||
|
||||
lineLengths = computeLineLengths('B12345\n0123456789\n0123A567\n0123456');
|
||||
expect(segmentDiff(lineLengths, {line: 2, column: 4}, {line: 0, column: 0}))
|
||||
startOfLinePositions =
|
||||
computeStartOfLinePositions('B12345\n0123456789\n0123A567\n0123456');
|
||||
expect(segmentDiff(startOfLinePositions, {line: 2, column: 4}, {line: 0, column: 0}))
|
||||
.toEqual(-4 - 1 - 10 - 1 - 6 + 0);
|
||||
|
||||
lineLengths = computeLineLengths('0123B5\n0123456789\nA1234567\n0123456');
|
||||
expect(segmentDiff(lineLengths, {line: 2, column: 0}, {line: 0, column: 4}))
|
||||
startOfLinePositions =
|
||||
computeStartOfLinePositions('0123B5\n0123456789\nA1234567\n0123456');
|
||||
expect(segmentDiff(startOfLinePositions, {line: 2, column: 0}, {line: 0, column: 4}))
|
||||
.toEqual(0 - 1 - 10 - 1 - 6 + 4);
|
||||
});
|
||||
});
|
||||
|
||||
describe('offsetSegment()', () => {
|
||||
it('should return an identical marker if offset is 0', () => {
|
||||
const lineLengths = computeLineLengths('012345\n0123456789\n01234567\n0123456');
|
||||
const startOfLinePositions =
|
||||
computeStartOfLinePositions('012345\n0123456789\r\n01234567\n0123456');
|
||||
const marker = {line: 2, column: 3};
|
||||
expect(offsetSegment(lineLengths, marker, 0)).toBe(marker);
|
||||
expect(offsetSegment(startOfLinePositions, marker, 0)).toBe(marker);
|
||||
});
|
||||
|
||||
it('should return a new marker offset by the given chars', () => {
|
||||
const lineLengths = computeLineLengths('012345\n0123456789\n012*4567\n0123456');
|
||||
const startOfLinePositions =
|
||||
computeStartOfLinePositions('012345\n0123456789\r\n012*4567\n0123456');
|
||||
const marker = {line: 2, column: 3};
|
||||
expect(offsetSegment(lineLengths, marker, 1)).toEqual({line: 2, column: 4});
|
||||
expect(offsetSegment(lineLengths, marker, 2)).toEqual({line: 2, column: 5});
|
||||
expect(offsetSegment(lineLengths, marker, 4)).toEqual({line: 2, column: 7});
|
||||
expect(offsetSegment(lineLengths, marker, 8)).toEqual({line: 3, column: 2});
|
||||
expect(offsetSegment(lineLengths, marker, -1)).toEqual({line: 2, column: 2});
|
||||
expect(offsetSegment(lineLengths, marker, -2)).toEqual({line: 2, column: 1});
|
||||
expect(offsetSegment(lineLengths, marker, -4)).toEqual({line: 1, column: 10});
|
||||
expect(offsetSegment(lineLengths, marker, -6)).toEqual({line: 1, column: 8});
|
||||
expect(offsetSegment(startOfLinePositions, marker, 1)).toEqual({line: 2, column: 4});
|
||||
expect(offsetSegment(startOfLinePositions, marker, 2)).toEqual({line: 2, column: 5});
|
||||
expect(offsetSegment(startOfLinePositions, marker, 4)).toEqual({line: 2, column: 7});
|
||||
expect(offsetSegment(startOfLinePositions, marker, 6)).toEqual({line: 3, column: 0});
|
||||
expect(offsetSegment(startOfLinePositions, marker, 8)).toEqual({line: 3, column: 2});
|
||||
expect(offsetSegment(startOfLinePositions, marker, 20)).toEqual({line: 3, column: 14});
|
||||
expect(offsetSegment(startOfLinePositions, marker, -1)).toEqual({line: 2, column: 2});
|
||||
expect(offsetSegment(startOfLinePositions, marker, -2)).toEqual({line: 2, column: 1});
|
||||
expect(offsetSegment(startOfLinePositions, marker, -3)).toEqual({line: 2, column: 0});
|
||||
expect(offsetSegment(startOfLinePositions, marker, -4)).toEqual({line: 1, column: 10});
|
||||
expect(offsetSegment(startOfLinePositions, marker, -6)).toEqual({line: 1, column: 8});
|
||||
expect(offsetSegment(startOfLinePositions, marker, -16)).toEqual({line: 0, column: 5});
|
||||
});
|
||||
});
|
||||
});
|
@ -11,7 +11,7 @@ import {absoluteFrom} from '../../../src/ngtsc/file_system';
|
||||
import {runInEachFileSystem} from '../../../src/ngtsc/file_system/testing';
|
||||
import {RawSourceMap} from '../../src/sourcemaps/raw_source_map';
|
||||
import {SegmentMarker} from '../../src/sourcemaps/segment_marker';
|
||||
import {Mapping, SourceFile, computeLineLengths, extractOriginalSegments, findLastMappingIndexBefore, parseMappings} from '../../src/sourcemaps/source_file';
|
||||
import {Mapping, SourceFile, computeStartOfLinePositions, extractOriginalSegments, findLastMappingIndexBefore, parseMappings} from '../../src/sourcemaps/source_file';
|
||||
|
||||
runInEachFileSystem(() => {
|
||||
describe('SourceFile and utilities', () => {
|
||||
@ -482,17 +482,17 @@ runInEachFileSystem(() => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('computeLineLengths()', () => {
|
||||
it('should compute the length of each line in the given string', () => {
|
||||
expect(computeLineLengths('')).toEqual([0]);
|
||||
expect(computeLineLengths('abc')).toEqual([3]);
|
||||
expect(computeLineLengths('\n')).toEqual([0, 0]);
|
||||
expect(computeLineLengths('\n\n')).toEqual([0, 0, 0]);
|
||||
expect(computeLineLengths('abc\n')).toEqual([3, 0]);
|
||||
expect(computeLineLengths('\nabc')).toEqual([0, 3]);
|
||||
expect(computeLineLengths('abc\ndefg')).toEqual([3, 4]);
|
||||
expect(computeLineLengths('abc\r\n')).toEqual([3, 0]);
|
||||
expect(computeLineLengths('abc\r\ndefg')).toEqual([3, 4]);
|
||||
describe('computeStartOfLinePositions()', () => {
|
||||
it('should compute the cumulative length of each line in the given string', () => {
|
||||
expect(computeStartOfLinePositions('')).toEqual([0]);
|
||||
expect(computeStartOfLinePositions('abc')).toEqual([0]);
|
||||
expect(computeStartOfLinePositions('\n')).toEqual([0, 1]);
|
||||
expect(computeStartOfLinePositions('\n\n')).toEqual([0, 1, 2]);
|
||||
expect(computeStartOfLinePositions('abc\n')).toEqual([0, 4]);
|
||||
expect(computeStartOfLinePositions('\nabc')).toEqual([0, 1]);
|
||||
expect(computeStartOfLinePositions('abc\ndefg')).toEqual([0, 4]);
|
||||
expect(computeStartOfLinePositions('abc\r\n')).toEqual([0, 4]);
|
||||
expect(computeStartOfLinePositions('abc\r\ndefg')).toEqual([0, 4]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user