commit 118e7e7111a94340e2709fe68ef9d9ee4f0713b0
parent c10e36fc016cb265026a772571ce0a405df2ab71
Author: vanaigr <vanaigranov@gmail.com>
Date: Sun, 3 Aug 2025 21:39:31 -0500
test: add treesitter long lines benchmark
Diffstat:
2 files changed, 182 insertions(+), 6 deletions(-)
diff --git a/test/benchmark/decor_spec.lua b/test/benchmark/decor_spec.lua
@@ -8,7 +8,7 @@ describe('decor perf', function()
it('can handle long lines', function()
Screen.new(100, 101)
- local result = exec_lua [==[
+ local result = exec_lua(function()
local ephemeral_pattern = {
{ 0, 4, 'Comment', 11 },
{ 0, 3, 'Keyword', 12 },
@@ -61,7 +61,7 @@ describe('decor perf', function()
return true
end,
on_line = function()
- add_pattern(ephemeral_pattern, true)
+ add_pattern(ephemeral_pattern, true)
end,
})
@@ -69,16 +69,16 @@ describe('decor perf', function()
local total = {}
local provider = {}
- for i = 1, 100 do
+ for _ = 1, 100 do
local tic = vim.uv.hrtime()
- vim.cmd'redraw!'
+ vim.cmd 'redraw!'
local toc = vim.uv.hrtime()
table.insert(total, toc - tic)
table.insert(provider, pe - ps)
end
return { total, provider }
- ]==]
+ end)
local total, provider = unpack(result)
table.sort(total)
@@ -137,4 +137,39 @@ describe('decor perf', function()
)
print('\nTotal ' .. res)
end)
+
+ it('can handle long lines with treesitter highlighting', function()
+ Screen.new(100, 51)
+
+ local result = exec_lua(function()
+ local long_line = 'local a = { ' .. ('a = 5, '):rep(2000) .. '}'
+ vim.api.nvim_buf_set_lines(0, 0, 0, false, { long_line })
+ vim.api.nvim_win_set_cursor(0, { 1, 0 })
+ vim.treesitter.start(0, 'lua')
+
+ local total = {}
+ for _ = 1, 50 do
+ local tic = vim.uv.hrtime()
+ vim.cmd 'redraw!'
+ local toc = vim.uv.hrtime()
+ table.insert(total, toc - tic)
+ end
+
+ return { total }
+ end)
+
+ local total = unpack(result)
+ table.sort(total)
+
+ local ms = 1 / 1000000
+ local res = string.format(
+ 'min, 25%%, median, 75%%, max:\n\t%0.1fms,\t%0.1fms,\t%0.1fms,\t%0.1fms,\t%0.1fms',
+ total[1] * ms,
+ total[1 + math.floor(#total * 0.25)] * ms,
+ total[1 + math.floor(#total * 0.5)] * ms,
+ total[1 + math.floor(#total * 0.75)] * ms,
+ total[#total] * ms
+ )
+ print('\nTotal ' .. res)
+ end)
end)
diff --git a/test/benchmark/treesitter_spec.lua b/test/benchmark/treesitter_spec.lua
@@ -1,10 +1,11 @@
local n = require('test.functional.testnvim')()
+local Screen = require('test.functional.ui.screen')
local clear = n.clear
local exec_lua = n.exec_lua
describe('treesitter perf', function()
- setup(function()
+ before_each(function()
clear()
end)
@@ -47,4 +48,144 @@ describe('treesitter perf', function()
return vim.uv.hrtime() - start
]]
end)
+
+ local function test_long_line(_pos, _wrap, _line, grid)
+ local screen = Screen.new(20, 11)
+
+ local result = exec_lua(function(...)
+ local pos, wrap, line = ...
+
+ vim.api.nvim_buf_set_lines(0, 0, 0, false, { line })
+ vim.api.nvim_win_set_cursor(0, pos)
+ vim.api.nvim_set_option_value('wrap', wrap, { win = 0 })
+
+ vim.treesitter.start(0, 'lua')
+
+ local total = {}
+ for _ = 1, 100 do
+ local tic = vim.uv.hrtime()
+ vim.cmd 'redraw!'
+ local toc = vim.uv.hrtime()
+ table.insert(total, toc - tic)
+ end
+
+ return { total }
+ end, _pos, _wrap, _line)
+
+ screen:expect({ grid = grid or '' })
+
+ local total = unpack(result)
+ table.sort(total)
+
+ local ms = 1 / 1000000
+ local res = string.format(
+ 'min, 25%%, median, 75%%, max:\n\t%0.2fms,\t%0.2fms,\t%0.2fms,\t%0.2fms,\t%0.2fms',
+ total[1] * ms,
+ total[1 + math.floor(#total * 0.25)] * ms,
+ total[1 + math.floor(#total * 0.5)] * ms,
+ total[1 + math.floor(#total * 0.75)] * ms,
+ total[#total] * ms
+ )
+ print('\nTotal ' .. res)
+ end
+
+ local long_line = 'local a = { ' .. ('a = 5, '):rep(500) .. '}'
+ it('can redraw the beginning of a long line with wrapping', function()
+ local grid = [[
+ {15:^local} {25:a} {15:=} {16:{} {25:a} {15:=} {26:5}{16:,} {25:a}|
+ {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} |
+ {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,}|
+ {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}|
+ {16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} |
+ {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=}|
+ {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} |
+ {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a}|
+ {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} |
+ {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,}|
+ |
+ ]]
+ test_long_line({ 1, 0 }, true, long_line, grid)
+ end)
+
+ it('can redraw the middle of a long line with wrapping', function()
+ local grid = [[
+ {1:<<<}{26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} |
+ {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,}|
+ {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}|
+ {16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} |
+ {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=}|
+ {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} |
+ {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a}|
+ {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} |
+ {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,}|
+ {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a}^ {15:=} {26:5}|
+ |
+ ]]
+ test_long_line({ 1, math.floor(#long_line / 2) }, true, long_line, grid)
+ end)
+
+ it('can redraw the end of a long line with wrapping', function()
+ local grid = [[
+ {1:<<<}{25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=}|
+ {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} |
+ {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a}|
+ {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} |
+ {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,}|
+ {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}|
+ {16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} |
+ {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=}|
+ {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} |
+ {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {16:^}} |
+ |
+ ]]
+ test_long_line({ 1, #long_line - 1 }, true, long_line, grid)
+ end)
+
+ it('can redraw the beginning of a long line without wrapping', function()
+ local grid = [[
+ {15:^local} {25:a} {15:=} {16:{} {25:a} {15:=} {26:5}{16:,} {25:a}|
+ |
+ {1:~ }|*8
+ |
+ ]]
+ test_long_line({ 1, 0 }, false, long_line, grid)
+ end)
+
+ it('can redraw the middle of a long line without wrapping', function()
+ local grid = [[
+ {16:,} {25:a} {15:=} {26:5}{16:,} {25:a}^ {15:=} {26:5}{16:,} {25:a} {15:=} |
+ |
+ {1:~ }|*8
+ |
+ ]]
+ test_long_line({ 1, math.floor(#long_line / 2) }, false, long_line, grid)
+ end)
+
+ it('can redraw the end of a long line without wrapping', function()
+ local grid = [[
+ {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {16:^}} |
+ |
+ {1:~ }|*8
+ |
+ ]]
+ test_long_line({ 1, #long_line - 1 }, false, long_line, grid)
+ end)
+
+ local long_line_mb = 'local a = { ' .. ('À = 5, '):rep(500) .. '}'
+ it('can redraw the middle of a long line with multibyte characters', function()
+ local grid = [[
+ {1:<<<}{26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} |
+ {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,}|
+ {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}|
+ {16:,} {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} |
+ {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À} {15:=}|
+ {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À} |
+ {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À}|
+ {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} |
+ {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,}|
+ {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À}^ {15:=} {26:5}|
+ |
+ ]]
+ test_long_line({ 1, math.floor(#long_line_mb / 2) }, true, long_line_mb, grid)
+ end)
end)