From 9e221145e87bce4b1e603891a7c4a41449c3cbbd Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 10 Feb 2017 12:28:43 -0800 Subject: [PATCH 1/2] Avoid the possibility of stack overflow in spliceArray helper --- src/helpers.coffee | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/helpers.coffee b/src/helpers.coffee index df784c37b1..b0a84dc5e9 100644 --- a/src/helpers.coffee +++ b/src/helpers.coffee @@ -1,20 +1,27 @@ Point = require './point' -SpliceArrayChunkSize = 100000 - MULTI_LINE_REGEX_REGEX = /\\r|\\n|\r|\n|^\[\^|[^\\]\[\^/ module.exports = - spliceArray: (originalArray, start, length, insertedArray=[]) -> - if insertedArray.length < SpliceArrayChunkSize - originalArray.splice(start, length, insertedArray...) + spliceArray: (array, start, removedCount, insertedItems=[]) -> + oldLength = array.length + insertedCount = insertedItems.length + removedCount = Math.min(removedCount, oldLength - start) + lengthDelta = insertedCount - removedCount + newLength = oldLength + lengthDelta + + if lengthDelta > 0 + array.length = newLength + for i in [(newLength - 1)..(start + insertedCount)] by -1 + array[i] = array[i - lengthDelta] else - removedValues = originalArray.splice(start, length) - for chunkStart in [0..insertedArray.length] by SpliceArrayChunkSize - chunkEnd = chunkStart + SpliceArrayChunkSize - chunk = insertedArray.slice(chunkStart, chunkEnd) - originalArray.splice(start + chunkStart, 0, chunk...) - removedValues + for i in [(start + insertedCount)...newLength] by 1 + array[i] = array[i - lengthDelta] + array.length = newLength + + for value, i in insertedItems by 1 + array[start + i] = insertedItems[i] + return newlineRegex: /\r\n|\n|\r/g From 6a09c8a57dcaa0067c698871fd772249df7a79db Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 10 Feb 2017 13:25:29 -0800 Subject: [PATCH 2/2] Add mutation benchmark --- benchmarks/helpers.js | 19 ++++++++++++++++++- benchmarks/index.js | 1 + benchmarks/mutation.js | 21 +++++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 benchmarks/mutation.js diff --git a/benchmarks/helpers.js b/benchmarks/helpers.js index 5236b5348f..9bd206a5c9 100644 --- a/benchmarks/helpers.js +++ b/benchmarks/helpers.js @@ -1,9 +1,10 @@ const WORDS = require('../spec/helpers/words') const Random = require('random-seed') const random = new Random(Date.now()) +const {Point, Range} = require('..') exports.getRandomText = function (sizeInKB) { - const goalLength = sizeInKB * 1024 + const goalLength = Math.round(sizeInKB * 1024) let length = 0 let lines = [] @@ -41,3 +42,19 @@ exports.getRandomText = function (sizeInKB) { return lines.join('\n') + '\n' } + +exports.getRandomRange = function (buffer) { + const start = getRandomPoint(buffer) + const end = getRandomPoint(buffer) + if (end.isLessThan(start)) { + return new Range(end, start) + } else { + return new Range(start, end) + } +} + +function getRandomPoint (buffer) { + const row = random(buffer.getLineCount()) + const column = random(buffer.lineLengthForRow(row)) + return new Point(row, column) +} diff --git a/benchmarks/index.js b/benchmarks/index.js index 7b82b91714..e212686e85 100755 --- a/benchmarks/index.js +++ b/benchmarks/index.js @@ -1,3 +1,4 @@ #!/usr/bin/env node require('./construction') +require('./mutation') diff --git a/benchmarks/mutation.js b/benchmarks/mutation.js new file mode 100644 index 0000000000..f9cbfe1766 --- /dev/null +++ b/benchmarks/mutation.js @@ -0,0 +1,21 @@ +const helpers = require('./helpers') +const TextBuffer = require('..') + +let text = helpers.getRandomText(100) +let buffer = new TextBuffer({text}) +let displayLayer = buffer.addDisplayLayer({}) + +let t0 = Date.now() + +for (let i = 0; i < 1000; i++) { + buffer.setTextInRange( + helpers.getRandomRange(buffer), + helpers.getRandomText(0.5) + ) +} + +let t1 = Date.now() + +console.log('Mutation') +console.log('------------') +console.log('TextBuffer: %s ms', t1 - t0)