Closed AmerM137 closed 3 days ago
If the data is correct then maybe some of the commits here affected the performance https://github.com/pragtical/pragtical/commits/master/data/core/doc/init.lua
I would suspect of the followings:
You could try reverting some of those and seeing how it goes, or some of the others shown on the commit history of data/core/doc/init.lua
Another way of checking what is slowing things down is by using the profiler plugin: https://github.com/pragtical/plugins/tree/master/plugins/profiler
Also, is a good idea to take into account the enabled plugins, for example, have the same plugins on both lite-xl and pragtical just to make sure it isn't a plugin.
FWIW I'm also very interested in having low latency typing. I would try to replicate the measurements with typometer but I don't have any computer not running wayland right now :(
So I was doing some testing on my older MacBook Air and noticed the struggle for the machine when typing with lsp and much worse with the scm plugin enabled, so decided to take a crack on the co-routine scheduler (if it can be called that...) and made some adjustments to it as described here #174
@AmerM137 Can you give it a try? You should be able to measure it properly.
You would just need to replace core/init.lua with the linked file.
Still, I need to make the scm plugin behave better because recently noticed that it struggles under windows or low end systems. This update to scm https://github.com/pragtical/scm/pull/7 reduces the amount of updates to certain events which reduces the impact on the responsiveness of the editor.
Did some more tweaking... Instead of setting a 50% error margin on the maximum execution time of co-routines, on each run_threads iteration we check how many threads can be run without exceeding the maximum time allowed.
Updated Version: https://github.com/pragtical/pragtical/blob/ef5cb0455814a0b03bca9cb5a26f9ecbd451e1bc/data/core/init.lua
Exciting stuff. I'll give it a shot and update my numbers very soon!
Made some more changes:
Use the avg. runtime of co-routines to yield
We now keep track of every 1 second cycle in order to see how much time is left for executing co-routine tasks, by using the average execution time of co-routines to decide if we should execute it or skip it until next 1 second cycle.
Also these changes introduce
core.fps
which has the maximum frames per second that are actually possible to render, which can be used to accommodate to frame drops when performing some animations, scrolling, etc...
Looking forward for your results!
More stuff to improve overall editor responsiveness in scenarios where files with huge long lines are opened like compressed css or js files:
highlighter: on long lines notify first/last only Depending on installed plugins the update_notify call can get expensive and slow things down. With this change, it is now perform on first and last tokenization procedures, on first call it allows the visible first characters of the line to be updated for correct positioning calculations as plugins that need it.
The major drawback is when employing differently sized fonts for token types. This may cause wrong positioning calculations when scrolling, but it is preferred over a laggy code editor. It is not the norm to use different font sizes for token types on files with long lines. Currently only markdown language plugin makes such an use and users that may have done heavy customization to the styling of the token types.
Some videos showing a small test using this file https://github.com/digidoor/SICP/blob/master/theme.css. Without additional plugins it shows input lag on lite-xl and scrolling, meanwhile on Pragtical scrolling is smoother and input is faster. With additional plugins Lite XL interface doesn't even responds while on Pragtical you can still edit the file.
Vanilla Lite XL (master branch)
https://github.com/user-attachments/assets/b0b64d1f-2603-400c-b63b-0a121bce767d
Vanilla Pragtical (co-routine improvements)
https://github.com/user-attachments/assets/4d07a2d1-54ea-4f89-bf27-b91c1827dc81
Lite XL with Plugins (drawwhitespace, colorpreview, rainbowparens, minimap, indentguide, lsp)
Becomes unresponsive
Pragtical with Plugins (drawwhitespace, colorpreview, rainbowparens, minimap, indentguide, lsp and more)
https://github.com/user-attachments/assets/381d1a01-4f5d-427f-adff-a8a37fe46dea
New results tested at different fps. There is a clear improvement in input latency only when increasing fps. At 60 fps, It's only a marginal improvement vs other editors.
Built from PR #174 on windows with meson. Transitions off.
stat | 60fps | 90fps | 120fps | 144fps |
---|---|---|---|---|
mean | 24.24 | 21.67 | 18.71 | 19.00 |
std | 5.72 | 4.51 | 3.02 | 2.62 |
Thanks @AmerM137 for your test results, I think I finally got it with latest changes:
Main loop: burst events procecssing for 3s - When receiving events we reduce the wait time to match the rendering speed for the events that follow in order to process them earlier and reduce the input lag.
Input latency should be lower than lite-xl now:
https://github.com/user-attachments/assets/f57cf694-fa44-4bce-b693-8ca4a4b2a8fe
Testing Patch Against Latest PR Changes
diff --git a/data/core/init.lua b/data/core/init.lua
index 4bd8339c..ed2da295 100644
--- a/data/core/init.lua
+++ b/data/core/init.lua
@@ -1346,11 +1346,14 @@ local cycle_end_time = 0
---@type number
local main_loop_time = 0
+local event_start_time = nil
function core.step()
-- handle events
local did_keymap = false
+ local is_textinput = false
for type, a,b,c,d in system.poll_event do
+ is_textinput = type == "textinput"
if type == "textinput" and did_keymap then
did_keymap = false
elseif type == "mousemoved" then
@@ -1405,6 +1408,10 @@ function core.step()
core.root_view:draw()
renderer.end_frame()
+ if is_textinput then
+ print((system.get_time() - event_start_time) * 1000, "ms")
+ end
+
rendering_speed = math.max(0.001, system.get_time() - start_time)
if rendering_speed * config.fps < 1 then
@@ -1583,6 +1590,7 @@ function core.run()
end
else
-- run all threads, listen events and perform drawing as needed
+ event_start_time = system.get_time()
local did_redraw = false
if not next_step or system.get_time() >= next_step then
did_redraw = core.step()
Ok, so did my own benchmarks using TypoMeter and here are the results of that application:
With the input generated by TypoMeter and the testing patch posted on previous comment applied to both Pragtical and Lite XL, here are the results taken directly from the applications themself, measuring the time since registering the input event until the character is rendered on the interface:
Editor | Min | Max | Average |
---|---|---|---|
Pragtical | 1.9058650000261 | 2.8339249997771 | 2.19647337500755 |
Lite XL | 3.4161069997936 | 52.384641000117 | 36.695156788055 |
It seems that TypoMeter has issues measuring fast responses and system hiccups can cause the application to report incorrect values resulting on inconsistent results.
I think we should be good to merge. Going to test a bit more while doing some work with the editor.
Sounds good! I agree that typometer can be very finnicky. It would be great to have our own profiling tool in the editor. I used your patch and here are my numbers. It's looking really good!
@jgmdev it would be great if we make it easy to run these kinds of tests from within Pragtical. Can the input latency profiler become a simple plugin maybe?
@jgmdev it would be great if we make it easy to run these kinds of tests from within Pragtical. Can the input latency profiler become a simple plugin maybe?
Stitched something together just now and pushed it to plugins repo: https://github.com/pragtical/plugins/blob/master/plugins/input_latency.lua
I've been using Pragtical for a few weeks and I noticed higher than usual input lag compared to other editors. I compared it directly to LiteXL and it looks like there's about a ~2x increase in input lag. I am including data from Sublime & Vscode also for comparison.
Program used to measure input latency -> https://github.com/pavelfatin/typometer Even though it's a little buggy (sometimes it freezes and stops collecting data), I am confident the measurements translate to user experience. As an example, I felt high input lag when running an IPython REPL inside VSCode's integrated terminal. I measured it with
typometer
and it turned out that my latency is ~50ms which is not easy to ignore.@jgmdev I am happy to help with this issue, I just don't know where to start. Let me know what I can do.
Note: the issue has been ongoing for a few versions now. This is not a regression caused by the latest version.
System specs: Windows 11 Pro -- Version 10.0.22631 Build 22631 Pragtical v3.4.2-jit