-
Notifications
You must be signed in to change notification settings - Fork 366
Replace _mappings array with data structure
#150
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| /* -*- Mode: js; js-indent-level: 2; -*- */ | ||
| /* | ||
| * Copyright 2014 Mozilla Foundation and contributors | ||
| * Licensed under the New BSD license. See LICENSE or: | ||
| * http://opensource.org/licenses/BSD-3-Clause | ||
| */ | ||
| if (typeof define !== 'function') { | ||
| var define = require('amdefine')(module, require); | ||
| } | ||
| define(function (require, exports, module) { | ||
|
|
||
| var util = require('./util'); | ||
|
|
||
| /** | ||
| * Determine whether mappingB is after mappingA with respect to generated | ||
| * position. | ||
| */ | ||
| function generatedPositionAfter(mappingA, mappingB) { | ||
| // Optimized for most common case | ||
| var lineA = mappingA.generatedLine; | ||
| var lineB = mappingB.generatedLine; | ||
| var columnA = mappingA.generatedColumn; | ||
| var columnB = mappingB.generatedColumn; | ||
| return lineB > lineA || lineB == lineA && columnB >= columnA || | ||
| util.compareByGeneratedPositions(mappingA, mappingB) <= 0; | ||
| } | ||
|
|
||
| /** | ||
| * A data structure to provide a sorted view of accumulated mappings in a | ||
| * performance conscious manner. It trades a neglibable overhead in general | ||
| * case for a large speedup in case of mappings being added in order. | ||
| */ | ||
| function MappingList() { | ||
| this._array = []; | ||
| this._sorted = true; | ||
| // Serves as infimum | ||
| this._last = {generatedLine: -1, generatedColumn: 0}; | ||
| } | ||
|
|
||
| /** | ||
| * Iterate through internal items. NOTE: order is NOT guaranteed. | ||
| */ | ||
| MappingList.prototype.unsortedForEach = function MappingList_forEach() { | ||
| Array.prototype.forEach.apply(this._array, arguments); | ||
| }; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This method is unused, right? I think we should remove it -- it doesn't guarantee sorted order and I think that is a potential foot gun in the future. If we don't need it, let's remove it.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So, it does get used here https://github.com/crisptrutski/source-map/blob/optimistic-add-mapping/lib/source-map/source-map-generator.js#L190. Used to make local mutations to the elements, so no cares about order. Could skip return value in wrapper to obliviate one self-harm vector, but yeah it'd be confusing with functions with non-scoped side effects. To be honest I don't see much scope for reuse of this class though - passing in comparator as function was too much overhead so now it's really tightly coupled and just an implementation detail of the generator. How about an ignoble
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about we just rename it |
||
|
|
||
| /** | ||
| * Add the given source mapping. | ||
| * | ||
| * @param Object aMapping | ||
| */ | ||
| MappingList.prototype.add = function MappingList_add(aMapping) { | ||
| var mapping; | ||
| if (generatedPositionAfter(this._last, aMapping)) { | ||
| this._last = aMapping; | ||
| this._array.push(aMapping); | ||
| } else { | ||
| this._sorted = false; | ||
| this._array.push(aMapping); | ||
| } | ||
| }; | ||
|
|
||
| /** | ||
| * Returns the flat array representation of this structure. | ||
| * | ||
| * WARNING: Returns internal data without copying, for performance | ||
| */ | ||
| MappingList.prototype.toArray = function MappingList_toArray() { | ||
| if (this._sorted) { | ||
| return this._array; | ||
| } else { | ||
| // Sort runs in place | ||
| this._sorted = true; | ||
| return this._array.sort(util.compareByGeneratedPositions); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Still need to
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wanted to sort in place for the amortizing behaviour, but yeah missing a |
||
| } | ||
| }; | ||
|
|
||
| exports.MappingList = MappingList; | ||
|
|
||
| }); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To justify this unrolling, it provided a slightly over 2x speedup in my testing. Roughly corresponds to the
onlyCompareGeneratedflag in the util function.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add that as a comment then, so it is clear to future readers?