mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-11-10 18:24:09 +03:00
Merge pull request #13820 from atom/mb-ns-long-lines
Avoid hangs when opening minified files
This commit is contained in:
commit
4a3c92f689
@ -26,7 +26,7 @@ export default async function ({test}) {
|
||||
console.log(text.length / 1024)
|
||||
|
||||
let t0 = window.performance.now()
|
||||
const buffer = new TextBuffer(text)
|
||||
const buffer = new TextBuffer({text})
|
||||
const editor = new TextEditor({buffer, largeFileMode: true})
|
||||
atom.workspace.getActivePane().activateItem(editor)
|
||||
let t1 = window.performance.now()
|
||||
|
97
benchmarks/text-editor-long-lines.bench.js
Normal file
97
benchmarks/text-editor-long-lines.bench.js
Normal file
@ -0,0 +1,97 @@
|
||||
/** @babel */
|
||||
|
||||
import path from 'path'
|
||||
import fs from 'fs'
|
||||
import {TextEditor, TextBuffer} from 'atom'
|
||||
|
||||
const SIZES_IN_KB = [
|
||||
512,
|
||||
1024,
|
||||
2048
|
||||
]
|
||||
const REPEATED_TEXT = fs.readFileSync(path.join(__dirname, '..', 'spec', 'fixtures', 'sample.js'), 'utf8').replace(/\n/g, '')
|
||||
const TEXT = REPEATED_TEXT.repeat(Math.ceil(SIZES_IN_KB[SIZES_IN_KB.length - 1] * 1024 / REPEATED_TEXT.length))
|
||||
|
||||
export default async function ({test}) {
|
||||
const data = []
|
||||
|
||||
const workspaceElement = atom.views.getView(atom.workspace)
|
||||
document.body.appendChild(workspaceElement)
|
||||
|
||||
atom.packages.loadPackages()
|
||||
await atom.packages.activate()
|
||||
|
||||
console.log(atom.getLoadSettings().resourcePath);
|
||||
|
||||
for (let pane of atom.workspace.getPanes()) {
|
||||
pane.destroy()
|
||||
}
|
||||
|
||||
for (const sizeInKB of SIZES_IN_KB) {
|
||||
const text = TEXT.slice(0, sizeInKB * 1024)
|
||||
console.log(text.length / 1024)
|
||||
|
||||
let t0 = window.performance.now()
|
||||
const buffer = new TextBuffer({text})
|
||||
const editor = new TextEditor({buffer, largeFileMode: true})
|
||||
editor.setGrammar(atom.grammars.grammarForScopeName('source.js'))
|
||||
atom.workspace.getActivePane().activateItem(editor)
|
||||
let t1 = window.performance.now()
|
||||
|
||||
data.push({
|
||||
name: 'Opening a large single-line file',
|
||||
x: sizeInKB,
|
||||
duration: t1 - t0
|
||||
})
|
||||
|
||||
const tickDurations = []
|
||||
for (let i = 0; i < 20; i++) {
|
||||
await timeout(50)
|
||||
t0 = window.performance.now()
|
||||
await timeout(0)
|
||||
t1 = window.performance.now()
|
||||
tickDurations[i] = t1 - t0
|
||||
}
|
||||
|
||||
data.push({
|
||||
name: 'Max time event loop was blocked after opening a large single-line file',
|
||||
x: sizeInKB,
|
||||
duration: Math.max(...tickDurations)
|
||||
})
|
||||
|
||||
t0 = window.performance.now()
|
||||
editor.setCursorScreenPosition(editor.element.screenPositionForPixelPosition({
|
||||
top: 100,
|
||||
left: 30
|
||||
}))
|
||||
t1 = window.performance.now()
|
||||
|
||||
data.push({
|
||||
name: 'Clicking the editor after opening a large single-line file',
|
||||
x: sizeInKB,
|
||||
duration: t1 - t0
|
||||
})
|
||||
|
||||
t0 = window.performance.now()
|
||||
editor.element.setScrollTop(editor.element.getScrollTop() + 100)
|
||||
t1 = window.performance.now()
|
||||
|
||||
data.push({
|
||||
name: 'Scrolling down after opening a large single-line file',
|
||||
x: sizeInKB,
|
||||
duration: t1 - t0
|
||||
})
|
||||
|
||||
editor.destroy()
|
||||
buffer.destroy()
|
||||
await timeout(10000)
|
||||
}
|
||||
|
||||
workspaceElement.remove()
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
function timeout (duration) {
|
||||
return new Promise((resolve) => setTimeout(resolve, duration))
|
||||
}
|
@ -16,6 +16,7 @@ TextEditorElement = require './text-editor-element'
|
||||
{isDoubleWidthCharacter, isHalfWidthCharacter, isKoreanCharacter, isWrapBoundary} = require './text-utils'
|
||||
|
||||
ZERO_WIDTH_NBSP = '\ufeff'
|
||||
MAX_SCREEN_LINE_LENGTH = 500
|
||||
|
||||
# Essential: This class represents all essential editing state for a single
|
||||
# {TextBuffer}, including cursor and selection positions, folds, and soft wraps.
|
||||
@ -2964,7 +2965,7 @@ class TextEditor extends Model
|
||||
else
|
||||
@getEditorWidthInChars()
|
||||
else
|
||||
Infinity
|
||||
MAX_SCREEN_LINE_LENGTH
|
||||
|
||||
###
|
||||
Section: Indentation
|
||||
|
@ -8,6 +8,8 @@ ScopeDescriptor = require './scope-descriptor'
|
||||
TokenizedBufferIterator = require './tokenized-buffer-iterator'
|
||||
NullGrammar = require './null-grammar'
|
||||
|
||||
MAX_LINE_LENGTH_TO_TOKENIZE = 500
|
||||
|
||||
module.exports =
|
||||
class TokenizedBuffer extends Model
|
||||
grammar: null
|
||||
@ -251,6 +253,8 @@ class TokenizedBuffer extends Model
|
||||
|
||||
buildTokenizedLineForRowWithText: (row, text, ruleStack = @stackForRow(row - 1), openScopes = @openScopesForRow(row)) ->
|
||||
lineEnding = @buffer.lineEndingForRow(row)
|
||||
if text.length > MAX_LINE_LENGTH_TO_TOKENIZE
|
||||
text = text.slice(0, MAX_LINE_LENGTH_TO_TOKENIZE)
|
||||
{tags, ruleStack} = @grammar.tokenizeLine(text, ruleStack, row is 0, false)
|
||||
new TokenizedLine({openScopes, text, tags, ruleStack, lineEnding, @tokenIterator})
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user