Ultisnips: UltiSnip is very slow

Created on 6 Feb 2018  路  23Comments  路  Source: SirVer/ultisnips

My alt+[1-9] have been bound to tabpage 1-9, and when I press alt+1-9 to swith tab there is a noticeable delay if UltiSnip has been enabled:

FUNCTIONS SORTED ON TOTAL TIME
count  total (s)   self (s)  function
  149   9.742292   0.142725  <SNR>147_OnBufferEnter()
  149   9.234464             UltiSnips#SnippetsInCurrentScope()
  156   1.652028   0.009707  <SNR>98_on_window_changed()
  151   1.641614   0.015714  airline#update_statusline()
  151   1.625000   0.007856  <SNR>127_invoke_funcrefs()
  151   1.416678   0.120412  253()
10466   1.133411   0.485156  airline#highlighter#get_highlight()
 2142   1.045088   0.081462  <SNR>138_exec_separator()
  755   1.025652   0.010257  <SNR>142_get_seperator()
  906   0.983512   0.036925  <SNR>142_get_transitioned_seperator()
 1812   0.946587   0.025405  airline#highlighter#add_separator()
 4672   0.871761   0.259872  airline#highlighter#exec()
  149   0.681060   0.031807  <SNR>65_updateData()
  109   0.643125   0.010170  airline#check_mode()
   55   0.620835   0.085390  airline#highlighter#highlight()
20932   0.567701             <SNR>138_get_syn()
  149   0.526273   0.047099  signature#sign#Refresh()
 4284   0.514009   0.030675  airline#themes#get_highlight()
  149   0.415597             <SNR>147_OnFileReadyToParse()
  298   0.325507   0.026431  fuf#saveDataFile()

FUNCTIONS SORTED ON SELF TIME
count  total (s)   self (s)  function
  149              9.234464  UltiSnips#SnippetsInCurrentScope()
20932              0.567701  <SNR>138_get_syn()
10466   1.133411   0.485156  airline#highlighter#get_highlight()
  149              0.415597  <SNR>147_OnFileReadyToParse()
  298              0.274618  l9#writeFile()
 4672   0.871761   0.259872  airline#highlighter#exec()
  298              0.214312  signature#mark#GetList()
 7748   0.238054   0.210231  signature#sign#Remove()
  298              0.165979  l9#readFile()
  149   9.742292   0.142725  <SNR>147_OnBufferEnter()
  151   1.416678   0.120412  253()
  150              0.098693  lfMru#record()
  298              0.096698  fuf#updateMruList()
 4672              0.096379  <SNR>138_CheckDefined()
   55   0.620835   0.085390  airline#highlighter#highlight()
 2142   1.045088   0.081462  <SNR>138_exec_separator()
10466              0.080554  <SNR>138_get_array()
 1057              0.067045  <SNR>142_get_accented_line()
 1510   0.066206   0.060088  <SNR>143_get_section()
 4671              0.049927  <SNR>138_hl_group_exists()

and

FUNCTION  UltiSnips#SnippetsInCurrentScope()
Called 149 times
Total time:   9.234464
 Self time:   9.234464

count  total (s)   self (s)
  149              0.001553     let g:current_ulti_dict = {}
  149              0.000545     let all = get(a:, 1, 0)
  149              0.000126     if all
  149              0.002575       let g:current_ulti_dict_info = {}
  149              0.000099     endif
  149              9.228793     exec g:_uspy "UltiSnips_Manager.snippets_in_current_scope(" . all . ")"
  149              0.000362     return g:current_ulti_dict

Most helpful comment

@skywind3000 Thanks for the benchmarks.

I decided to remove the auto detection of changed files and instead added a BufWrite in snippet files that will trigger reloading. This means as long as you only edit snippets in the same Vim instance you use the snippets later, you still get auto-reloading - just not across Vim instances.

UltiSnips is an old plugin. Back in the days, 'rtp' of more than a handful of directories were rare, so the strategy made sense and was cheap. I just checked and my rtp contains > 50 directories now, this comes with the abundance of plugins and the way plugin managers work. So in this new world, doing it differently makes sense.

All 23 comments

I had the same problem when going into insert mode and typing space character.
I am using vim 8 and cygwin on windows 7.

After removing ultisnips the problem disappeared.
The function was something called "check change".

I also notice this when opening a file and switching from normal to insert mode, there is a visible lag between actually pressing a key and character apperiance. Also after some point editing becomes really slow, even with no switching between modes

I chose ultisnips because it is compatible with YouCompleteMe, now I temporarily switch back to snipmate because I found a way to get snipmate compatible with YCM too:

imap <expr> <m-e> pumvisible() ? '<c-g>u<Plug>snipMateTrigger' : '<Plug>snipMateTrigger'
imap <expr> <m-n> pumvisible() ? '<c-g>u<Plug>snipMateNextOrTrigger' : '<Plug>snipMateNextOrTrigger'
smap <m-n> <Plug>snipMateNextOrTrigger
imap <expr> <m-p> pumvisible() ? '<c-g>u<Plug>snipMateBack' : '<Plug>snipMateBack'
smap <m-p> <Plug>snipMateBack
imap <expr> <m-m> pumvisible() ? '<c-g>u<Plug>snipMateShow' : '<Plug>snipMateShow'

This keymaps help me to reuse snipmate with YCM again.

ALT+e: expand snip
ALT+n: next position
ALT+p: previous position
ALT+m: show snip suggestions

Snipmate has less feature than UltiSnip, but it is fast and could be trusted.

@skywind3000 Thats great, I'll try to apply it to my config, but I already see that it may be difficult with snipmate.
I've achieved triggereng snippets by Tab and Enter, and also being able to do all my Tab-completions with deoplete by defining theese 3 functions:

let g:UltiSnipsExpandTrigger="<C-J>"
let g:UltiSnipsJumpForwardTrigger = "<NUL>"
let g:UltiSnipsJumpBackwardTrigger = "<NUL>"

let g:ulti_expand_or_jump_res = 0
function! <SID>ExpandOrClosePopup()
    let snippet = UltiSnips#ExpandSnippetOrJump()
    if g:ulti_expand_or_jump_res > 0
        return snippet
    else
        let close_popup = deoplete#close_popup()
        return close_popup
    endif
endfunction

function! Neotab()
    if pumvisible() == 1
        return "\<C-n>"
    else
        let snippet = UltiSnips#ExpandSnippetOrJump()
        if g:ulti_expand_or_jump_res > 0
            return snippet
        else
            return "\<Tab>"
        endif
    endif
endfunction

function! Neostab()
    if pumvisible() == 1
        return "\<C-p>"
    else
        let snippet = UltiSnips#JumpBackwards()
        if g:ulti_expand_or_jump_res > 0
            return snippet
        else
            return "\<S-Tab>"
        endif
endfunction

inoremap <silent><expr><CR> pumvisible() ? "<C-R>=<SID>ExpandOrClosePopup()<CR>" : delimitMate#WithinEmptyPair() ? "\<C-R>=delimitMate#ExpandReturn()\<CR>" : "\<Cr>"
inoremap <silent><Tab>   <C-R>=Neotab()<CR>
snoremap <silent><Tab>   <Esc>:call UltiSnips#JumpForwards()<CR>
inoremap <silent><S-Tab> <C-R>=Neostab()<CR>
snoremap <silent><S-Tab> <Esc>:call UltiSnips#JumpBackwards()<CR>

Explanations are avalible here.
Basically when popup is open Tab scrolls through, and Enter expands snippet if it matches. Within the snippet I can mowe between tabstops with Tab when popup is invisible, and with Enter when popup is visible. Shifr+Tab jumps backwards. But since Ultisnips is slow, and snipmate don't provide functions (or I didn't found one) I don't really know how to be.

Are some of your snippet files on network mounts? If not, do you have many directories with snippets in your rtp?

While I'm expirienncing this too, I'll ancwer for myself:
I use neovim with standart Ultisnips + vim-snippets installation.
My own created snippets are stored in one file c.snippets, created by :UltiSnipsEdit and located in ~/.vim/UltiSnips.
Just after startup I'm expiriencing a delay bfore text appears. Switching modes is instant, only first keypress lags. However after some period of time my neovim starts lagging a lot while i'm typing. I'm editing a file that is actually on remote server, that is connected via sshfs, but I believe that it is not the case, and i think that i've expirienced lags while editing local files too. Files are C code around 1200 lines long

@andreyorst The original bug is not about Neovim. Neovim is not currently supported.

@SirVer I undersand. Well i'll wait then for ultisnips neovim maintainer. If there ever will be one .

I don't have any network filesystem mounted, all my files are located right in my local SSD. and SSD hardware problems could be excluded here too, SSD works very well.

One thing I forgot to mention is that I am using GVIM on Windows. Does that matter ?

@skywind3000 Yes, windows matters. My guess is that this is an issue of slow stat calls in mingw which I experienced before. Please try the following branch: https://github.com/SirVer/ultisnips/compare/issue_932?expand=1

This disables auto-reload of snippet files, i.e. if you edit a snippet you have to quit and restart Vim to get the changed definition. Please give this a try and report back if that fixes the issue. We can then consider if this is a possible workaround or not.

Thanks @SirVer, the patch works perfectly, see the profile before and after using the patch:

before:

FUNCTIONS SORTED ON SELF TIME
count  total (s)   self (s)  function
   75              4.496160  UltiSnips#SnippetsInCurrentScope()
  150              0.450893  fuf#updateMruList()
  150              0.281874  l9#writeFile()
   75              0.207788  <SNR>129_OnFileReadyToParse()
  150              0.165300  l9#readFile()
  150   0.321197   0.136263  fuf#loadDataFile()
  152              0.117708  signature#mark#GetList()
   75              0.100483  lfMru#record()
 3952   0.110175   0.097733  signature#sign#Remove()
  150   0.390774   0.095766  fuf#saveDataFile()
   75   4.783235   0.072654  <SNR>129_OnBufferEnter()
   87              0.062353  <SNR>129_Pyeval()
  450              0.060147  Vim_NeatBuffer()
  150              0.035168  <SNR>129_UpdateMatches()
   75   1.196036   0.032352  <SNR>72_updateData()
  300   0.032768   0.029422  l9#concatPaths()
   76   0.263848   0.022586  signature#sign#Refresh()
  150              0.022281  <SNR>107_Highlight_Matching_Pair()
    8   0.015525   0.015119  <SNR>129_OnBufferUnload()
  450   0.074854   0.014708  Vim_NeatGuiTabLabel()

after:

FUNCTIONS SORTED ON SELF TIME
count  total (s)   self (s)  function
  300              0.849454  fuf#updateMruList()
  300              0.542375  l9#writeFile()
  153   0.408657   0.407396  <SNR>129_OnFileReadyToParse()
  150              0.312440  UltiSnips#SnippetsInCurrentScope()
  300              0.297148  l9#readFile()
  300   0.575635   0.245439  fuf#loadDataFile()
  300              0.238496  signature#mark#GetList()
 7800   0.220859   0.193898  signature#sign#Remove()
  300   0.754503   0.186537  fuf#saveDataFile()
  153              0.182928  lfMru#record()
  150   0.851440   0.135544  <SNR>129_OnBufferEnter()
  908              0.117764  Vim_NeatBuffer()
  168              0.104293  <SNR>129_Pyeval()
  150   2.265747   0.084581  <SNR>72_updateData()
    6   0.077478   0.076863  sy#repo#get_diff_start()
  300              0.069125  <SNR>129_UpdateMatches()
    4   0.517258   0.057522  Tools_FileSwitch()
  600   0.058639   0.052267  l9#concatPaths()
  150   0.532599   0.045670  signature#sign#Refresh()
  307              0.043932  <SNR>107_Highlight_Matching_Pair()

It appears that disable auto-reload is really helpful for performance on windows.

So, for most users including me (who just use snips, never edit one), auto-reload is nearly needless and could be totally removed. 99.9% of time, I don't need refresh snips. The functionality for 0.1% should not delay other 99.9% 's workflow.

I don't mind if I need restart vim or call a new command like :UltiSnipsReload to refresh snips every time I change them and I am happy to re-enter vim or execute a reload command manually.

Or, at least a new option to disable auto-reload (which is turn on by default) ?

The functionality for 0.1% should not delay other 99.9% 's workflow.

I think this is not correct. When editing snippets, reloading is very very useful, and that is not a 0.1% use case. However I see multiple possible approaches:

  1. Add an option to disable auto reloading. Auto reloading must stay the default, since changing it is a backwards incompatible change and would lead to tons of reported issues. A new command like you are suggesting should be added to force-reload snippets.

  2. Change UltiSnips to not look for changed snippets on each snippet expansion. Instead, whenever Vim writes a file, reload snippets (ideally in the background). This looses the functionality of changing snippets outside of Vim and still have them be reloaded, but that seems an esoteric feature to me. It also would still lead to stutter (of 4sec in your case) when saving a file if we cannot figure out how to do it in the background.

I think 2 is the least intrusive way of getting the performance improvements to everybody. 1. has the issue that it is hard to discover for people running into performance issues.

I prefer 1, when I am editing snippets I can enable auto reloading, like you said, it is convenient, and I will turn it off when I finish editing them.

Maybe we can have option 1 first ? Because option 1 will solve the existent performance issue immediately. and later, we can explore a better way to handle snippets auto-reloading properly if we have time.

Or, an g:UltiSnipsReloadStrategy could be introduced ?

strategy 0 : (default) traditional auto-reload
strategy 1: manually
strategy 2: reload on file saving.
strategy 3: other methods like background reloading or incremental reloading ??

Change UltiSnips to not look for changed snippets on each snippet expansion.

You mean that every time Ultisnips expands snippet it reparses all snippet files for current filetype to find whenever changes were made? Maybe that's why ultisnips has such low performance on my GPD Pocket? Every expand is about a second.

You mean that every time Ultisnips expands snippet it reparses all snippet files for current filetype to find whenever changes were made?

No, UltiSnips does only reparses a file if it has changed. It determines if a file has changed by looking at the sha1 sum of it, i.e. whenever you expand a snippet, it reads all potential snippet files (i.e. all files matching for the filetype) and creates a shasum of them. If it has not changed since the last time, it does no further work. So on snippet expansion, UltiSnips does this work:

  1. iterate all rtp and look for UltiSnips directory (or other snippet directories configured).
  2. list all files in every found UltiSnips directory and check if the filename matches the requested filetype(s).
  3. for every file, create a fingerprint (currently sha1) and check if this fingerprint differed to the last run.
  4. for every changed file, parse it and add its snippets.

@skywind3000 I am not yet ready to commit on one correct implementation going forward - I'd like a bit more data before that. Could you retest the same branch (https://github.com/SirVer/ultisnips/compare/issue_932?expand=1) once more and report the profile, please?

I did the following changes there:

  • I reverted the caching behaviour to how master behaves, i.e. changed snippets are detected again.
  • I swapped out the fingerprinting of files (i.e. step 3 from above) to not use hashlib.sha1 (~40microseconds on my system), but instead use os.stat().st_mtime (~10microseconds).

My hunch is that it should be slow again for you, because I believe that the problem is in stat and readdir being slow in Windows, i.e. I think the time you see is spend in 2., not 3. But maybe the reading + hashing of the file contents is actually much slower on windows, in that case this patch might help too.

original

FUNCTIONS SORTED ON SELF TIME
count  total (s)   self (s)  function
   84              4.748141  UltiSnips#SnippetsInCurrentScope()
  174              0.478079  fuf#updateMruList()
15204              0.399587  <SNR>145_get_syn()
 7602   0.801403   0.344420  airline#highlighter#get_highlight()
  174              0.303924  l9#writeFile()
   86   0.224201   0.223216  <SNR>155_OnFileReadyToParse()
 3804   0.681278   0.209804  airline#highlighter#exec()
    1              0.170385  <SNR>10_SetupColorSchemes()
  174              0.145902  l9#readFile()
  178              0.144330  signature#mark#GetList()
   10   0.131555   0.130498  sy#repo#get_diff_start()
  174   0.286673   0.124994  fuf#loadDataFile()
 4628   0.133044   0.117062  signature#sign#Remove()
  174   0.422353   0.104387  fuf#saveDataFile()
   87   4.819930   0.085116  <SNR>155_OnBufferEnter()
   51   0.595128   0.084410  airline#highlighter#highlight()
   93              0.083104  lfMru#record()
   93   0.850729   0.074798  261()
    5   1.244110   0.069713  Tools_FileSwitch()
  362              0.065343  Vim_NeatBuffer()

after patch 1

FUNCTIONS SORTED ON SELF TIME
count  total (s)   self (s)  function
19696              0.493321  <SNR>145_get_syn()
  172              0.452411  fuf#updateMruList()
 9848   0.997342   0.432858  airline#highlighter#get_highlight()
  172              0.304421  l9#writeFile()
 5686   0.971548   0.303118  airline#highlighter#exec()
   86   0.257225   0.257042  <SNR>155_OnFileReadyToParse()
   85              0.251681  UltiSnips#SnippetsInCurrentScope()
  172              0.145330  l9#readFile()
  172              0.139866  signature#mark#GetList()
   88   0.988812   0.139160  airline#highlighter#highlight()
  172   0.286226   0.122686  fuf#loadDataFile()
 4472   0.130716   0.114590  signature#sign#Remove()
    8   0.109125   0.108064  sy#repo#get_diff_start()
  172   0.421929   0.103758  fuf#saveDataFile()
  118              0.086541  <SNR>155_Pyeval()
   86   0.520434   0.085127  <SNR>155_OnBufferEnter()
   91              0.079388  lfMru#record()
 5686              0.074834  <SNR>145_CheckDefined()
   91   0.845355   0.074401  261()
 9848              0.071162  <SNR>145_get_array()

after patch-2 you just posted

FUNCTIONS SORTED ON SELF TIME
count  total (s)   self (s)  function
   76              4.226268  UltiSnips#SnippetsInCurrentScope()
  152              0.392996  fuf#updateMruList()
14456              0.352993  <SNR>145_get_syn()
 7228   0.709530   0.306155  airline#highlighter#get_highlight()
  152              0.268579  l9#writeFile()
   76              0.222449  <SNR>155_OnFileReadyToParse()
 3792   0.632123   0.194806  airline#highlighter#exec()
  152              0.126556  l9#readFile()
  154              0.122298  signature#mark#GetList()
    8   0.108948   0.107882  sy#repo#get_diff_start()
  152   0.243425   0.103451  fuf#loadDataFile()
 4004   0.116026   0.101692  signature#sign#Remove()
  152   0.370498   0.089918  fuf#saveDataFile()
   54   0.587427   0.083957  airline#highlighter#highlight()
   77   4.285824   0.076926  <SNR>155_OnBufferEnter()
   81              0.070225  lfMru#record()
    4   1.130134   0.065039  Tools_FileSwitch()
   82   0.696587   0.060503  261()
  307              0.054927  Vim_NeatBuffer()
   83              0.054675  <SNR>155_Pyeval()

It seems patch-2 is helpless.

Most users are light-weight users who seldom edit their own snippet files everyday, and just use https://github.com/honza/vim-snippets directly.

As a non-hard-core user, I just created only 7-8 snippets and use them with vim-snippets, it fits my needs quite well. The last time I updated my snippet files is nearly 2 months ago.

So, I really don't mind restart vim if vim-snippets updated. Just like we need restart vim if some other plugin has been updated.

I have no idea if I don't update my snippets every day, what's the point to check snippets changes every time when buffer switching or someting else ? why must I suffer from slowing down my vim all time without any benefit for me ?

It is not just a performance issue on windows only, but also for linux, you just can't notice because your laptop is fast enough, but you can feel noticeable delay if running vim on a slow linux box, for example, my NAS has an Intel(R) Celeron(R) CPU J1900 @ 1.99GHz, UltiSnip is really slow on it.

There are 6K results on google about "vim ultisnip slow" now, vim is supposed to be a fast text editor even if running on a ARM based Raspberry Pi. UltiSnips is a great plugin on vimawesome.com, a good plugin should not become a performance killer, I wish it could run every where even on my NAS or my windows laptop.

For most light-weight users, snippets are not like tags. An auto refreshing mechanism is great but may not be a burden for them because they will not change their snippets everyday.

Can we just have an option to enable manual reload (which can be disabled by default) ? It will solve the problem immediately if users know what it is , then we will figure out a better detection method later.

Just a quick note on performance.

I use neovim on my android phone via termux, wich I use sometimes to make a quick drafts of some c/c++ code, that I'll use later, or to fix bugs, in my code wich I found while testing. I have private repos on gitlab, wich are mostly filled from phone during trip to work.

And I use such plugins like ALE, wich lints my cpp code every time I type single character, deoplete, that fuzzymatches and does semantic completion on the fly, airline, that integrates with tagbar, ALE, and some others, and autotags, that generates ctags on the fly asyncronously. That's a lot of work for my Nexus 5X, but it handles it well.

However ultisnips makes it so slow, that I choose to disable it on my phone completely. Well, i understand that neovim isn't supported, and ultisnips may not be tested on phones, but all other plugins work almost as fast as on my i7-3537U laptop.

At university teacher said that developer should develop his software on slow machine, so if it runs fast on it, it runs fast on everything. I don't agree with him, I believe that developer should use fastest machine to develop things with comfort, and only test them on slow machines. Well that's another story.

So ultisnips is slow for me too. I'ts not an issue on my laptop, but kind of an issue on my GPD Pocket and phone. Thats not a big issue though, I'm just using my own snippets based on abbreviations and hideiously complecs macroses on them. But the problem exists, that's for sure.

Most users are light-weight users who seldom edit their own snippet files everyday, and just use https://github.com/honza/vim-snippets directly.

This is the second time you say that, and I already discarded this argument as improbable. Please stop repeating it without providing data that it is true - it does not help keeping the issue focused on solving your problem at hand. In general, lacking hard data, my 10 years of UltiSnips issue tracking experience beats your personal opinion of what user do or not do most of the time.

why must I suffer from slowing down my vim all time without any benefit for me ?

You do not. This issue is acknowledging the problem in Windows and seeking for good solutions - as every issue should. We already identified a few possible solutions, but as a maintainer I need to find the correct long term fix and cannot settle for quick fixes - they will hound me forever, as I need to maintain them.

It is not just a performance issue on windows only, but also for linux, you just can't notice because your laptop is fast enough, but you can feel noticeable delay if running vim on a slow linux box, for example, my NAS has an Intel(R) Celeron(R) CPU J1900 @ 1.99GHz, UltiSnip is really slow on it.

What is slow about it? This issue at hand (#932) is about slowness of snippet expansion. We have conclusive data that this is slow on Windows only - not on Linux, not on Mac. Other slowness of UltiSnips belongs in different issues with supporting data. And in general, yes, UltiSnips is slow, because it has to run a diff algorithm (worst case: O(num_lines^3)) over the buffer and its last state every single time the buffer changes as long as a snippet is active. It is in all likelihood the most resource intensive plugin you have installed (@andreyorst This is also in response to your comment). Again, this is a different issue and needs to be discussed elsewhere - with repro case and numbers.

UltiSnips is a great plugin on vimawesome.com, a good plugin should not become a performance killer, I wish it could run every where even on my NAS or my windows laptop.

That would be nice, but the fact of the matter is: UltiSnips is a performance killer, it is an immensely complex plugin for the simple reason that Vim did not provide an API for tracking changes to a buffer over time. Right now, it is easy to run a snippet, undo it and send UltiSnips into diff algorithm that you will never see terminate. This was the only way of getting the features it has implemented back in the 7.4 days. Now with TextChanged and TextChangedI we might be lucky and get the same in O(n), however somebody needs to investigate and implement that.

Can we just have an option to enable manual reload (which can be disabled by default).

yes, of course we can. This is already proven by my first experiment, there does not seem to be a point in asking this again. Is that the best option? It more and more seems like it. It is not great for me, because it means more features to support, more documentation to write or review and more stuff that people need to learn about UltiSnips. So, please bear with me as I try to find simple solutions that would fix the problem too (i.e. changing the fingerprint solution to using os.stat - wouldn't it have been awesome if that would have solved the issue?). I am also not done with exploring the space, so I have one more test I need your number on (see below).

An auto refreshing mechanism is great but may not be a burden for them because they will not change their snippets everyday.

Fun fact: In the early days of UltiSnips, we gained most of our initial users switching from snipmate because UltiSnips was faster (still is) and because it had snippet auto reloading.

Let's get back to the issue at hand.

It seems patch-2 is helpless.

too bad, but as expected:

My hunch is that it should be slow again for you,

We already know that the problem is in kernelspace, likely IO (otherwise it would not be slow only for windows). With our experiments we have learned that calculating a shasum is not the slow part, it is nearly equally fast as doing os.stat. Remaining open question for me is now, if readdir is the slow part. In the latest change in the same branch I linked before, I avoid doing a readdir, doing it only once and caching the result. If this is now fast again, we have found the culprit and we can get away without introducing a new option. @skywind3000 Would you run the profile once more, please?

The latest profile for patch-3 is

FUNCTIONS SORTED ON SELF TIME
count  total (s)   self (s)  function
   83              4.421062  UltiSnips#SnippetsInCurrentScope()
  166              0.439900  fuf#updateMruList()
14292              0.374560  <SNR>146_get_syn()
 7146   0.751871   0.323873  airline#highlighter#get_highlight()
  166              0.280013  l9#writeFile()
   83              0.227742  <SNR>156_OnFileReadyToParse()
 3700   0.623379   0.191044  airline#highlighter#exec()
  166              0.142802  l9#readFile()
  166              0.127658  signature#mark#GetList()
  166   0.279739   0.119386  fuf#loadDataFile()
 4316   0.121026   0.106676  signature#sign#Remove()
  166   0.391815   0.098899  fuf#saveDataFile()
   83              0.077895  lfMru#record()
   83   4.732295   0.076661  <SNR>156_OnBufferEnter()
   52   0.537503   0.076205  airline#highlighter#highlight()
   83   0.817553   0.072126  261()
  332              0.057823  Vim_NeatBuffer()
   87              0.056607  <SNR>156_Pyeval()
   83   1.166252   0.053932  <SNR>74_updateData()
 7146              0.053437  <SNR>146_get_array()

By the way, reproduce steps:

  1. open 4 files in 4 tabpages.
  2. bind <m-1> to <m-9> for tab switching
  3. start profiling
  4. repeat press: <m-1>, <m-2>, <m-3> and <m-4> x20 times (4 x 20 times tab switching)
  5. exit vim.

@skywind3000 Thanks for the benchmarks.

I decided to remove the auto detection of changed files and instead added a BufWrite in snippet files that will trigger reloading. This means as long as you only edit snippets in the same Vim instance you use the snippets later, you still get auto-reloading - just not across Vim instances.

UltiSnips is an old plugin. Back in the days, 'rtp' of more than a handful of directories were rare, so the strategy made sense and was cheap. I just checked and my rtp contains > 50 directories now, this comes with the abundance of plugins and the way plugin managers work. So in this new world, doing it differently makes sense.

I have been out for two days, as soon as I get to my computer just now, I update ultisnips and test again.

here is the latest result:

FUNCTIONS SORTED ON SELF TIME
count  total (s)   self (s)  function
19768              0.464424  <SNR>152_get_syn()
  170              0.413618  fuf#updateMruList()
 9884   0.935972   0.404097  airline#highlighter#get_highlight()
  170              0.280035  l9#writeFile()
 5250   0.837379   0.254397  airline#highlighter#exec()
   85              0.234121  <SNR>166_OnFileReadyToParse()
   85              0.206852  UltiSnips#SnippetsInCurrentScope()
  170              0.136269  l9#readFile()
  172              0.128686  signature#mark#GetList()
  170   0.264986   0.112663  fuf#loadDataFile()
   71   0.793790   0.110761  airline#highlighter#highlight()
 4452   0.119256   0.105450  signature#sign#Remove()
    8   0.098457   0.097683  sy#repo#get_diff_start()
  170   0.387283   0.095056  fuf#saveDataFile()
   90              0.077139  lfMru#record()
   86   0.472730   0.077090  <SNR>166_OnBufferEnter()
   91   0.889265   0.076262  261()
 9884              0.067451  <SNR>152_get_array()
 5250              0.065803  <SNR>152_CheckDefined()
    1   0.062609   0.062560  <SNR>161_RefreshLine()

Apologize for my previous complaint and the misunderstanding for the hard choices ultisnips made.

And thank you very much, it works great on windows now.

@skywind3000 Thanks for consistently updating the numbers and flagging the issue in the first place. Enjoy UltiSnips!

Was this page helpful?
0 / 5 - 0 ratings