Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

YCM killing my vim with GoLang #1461

Closed
cfsalguero opened this issue Apr 16, 2015 · 62 comments
Closed

YCM killing my vim with GoLang #1461

cfsalguero opened this issue Apr 16, 2015 · 62 comments

Comments

@cfsalguero
Copy link

Since a couple of days, YCM started to use 99% CPU when using it with Go.
I've disabled Syntastic but there is no change.
There is any way to make it compile only when saving?

@vheon
Copy link
Contributor

vheon commented Apr 16, 2015

The go completer was merged 18 hours ago, so If you're saying that you have been experience these CPU overuse since a couple of days might not be YCM related. Are you working with large file by any chance?

@cfsalguero
Copy link
Author

Yes, I'm working with a really big project but, I ran PlauginInstall to update all plugins and everything seems to be working fine again.
Thank you so much. You made my day better.

@vheon
Copy link
Contributor

vheon commented Apr 16, 2015

@cfsalguero I was worried that you were experiencing CPU burst from this function. So if you still get those let us know.

@cfsalguero
Copy link
Author

It seems to be working much better but I'm still having issues when writing strings (even having let g:ycm_complete_in_strings = 0) or when the list of candidates is too long.
I'm going to investigate more before reopening the issue.

@cfsalguero
Copy link
Author

How can I debug it?

That is a very good question but I don't have a good answer.

@vheon
Copy link
Contributor

vheon commented Apr 16, 2015

Try to use YCM as always and if you experience the same behaviour then we could think to add some logging to that function to see if that is the real cause.

@cfsalguero cfsalguero reopened this Apr 16, 2015
@cfsalguero
Copy link
Author

Hi again,

Probably I would need to change the title and remove the word "killing', but it is working super slow.
Mainly on file having 200+ lines.
Please let me know if I can send you a log or something.

Thanks.

@Valloric
Copy link
Member

@ekfriis You might have some ideas.

@ekfriis
Copy link
Contributor

ekfriis commented Apr 16, 2015

Two ideas off the top of my head to narrow things down:

Is it the ycmd process or the gocode process that is saturating the CPU?

Are you completing things that have a lot of stuff that are possible completions? Example: a package with 10k costs defined in it.

@ekfriis
Copy link
Contributor

ekfriis commented Apr 16, 2015

s/costs/consts/

@Valloric that would violate causality

@Valloric
Copy link
Member

@ekfriis You can edit your comments on github. :) There's a little pencil icon in the top-right corner of a comment.

@cfsalguero
Copy link
Author

Don't know how to tell.
I only see vi using 100% CPU.
I'm online most part of the day. If you wish, I can help you using G+

@Valloric
Copy link
Member

If vim is using 100% CPU, this is unlikely to be caused by YCM; most YCM logic happens in ycmd, which is a separate process.

Do you perhaps have other vim plugins installed that might be interacting badly with YCM here? Try to reproduce the problem with only YCM loaded in your vimrc.

@cfsalguero
Copy link
Author

One more thing.
In Go you can have multiple files for the same package. Another file, not the one I was editing, had an error, and an error in the imports, so the errors list was almost empty because Go was only saying:

$ go build
can't load package: import cycle not allowed
package github.com/XXXXXXX/db/mysql
        imports github.com/XXXXXXX/db/mysql
import cycle not allowed

After fixing that, it started to work much better.
BTW, I've already tried only having YCM running and it was the same.

@ekfriis
Copy link
Contributor

ekfriis commented Apr 16, 2015

One idea: run in terminal

gocode -in=yourfile.go autocomplete yourfile.go 200 (or some other number,
this is the byte offset in the file to find completions for)

If this bless up the CPU, it is gocodes fault.

On Thu, Apr 16, 2015, 14:18 Carlos Salguero notifications@github.com
wrote:

One more thing.
In Go you can have multiple files for the same package. Another file, not
the one I was editing, had an error, and an error in the imports, so the
errors list was almost empty because Go was only saying:

$ go build
can't load package: import cycle not allowed
package github.com/XXXXXXX/db/mysql
imports github.com/XXXXXXX/db/mysql
import cycle not allowed

After fixing that, it started to work much better.
BTW, I've already tried only having YCM running and it was the same.


Reply to this email directly or view it on GitHub
#1461 (comment)
.

@cfsalguero
Copy link
Author

I dind't found a super slow line yet, but I was able to see (trying several times) a message that says: RuntimeError: Gocode returned empty json response
When that happens, the editor becomes slow.

@ekfriis
Copy link
Contributor

ekfriis commented Apr 17, 2015

@Valloric will YCM behave nicely if I throw exceptions in the case I don't understand the output from gocode? That is what I do now, for cases like @cfsalguero's above but I could just as easily return an empty set of completions instead of throwing.

@vheon
Copy link
Contributor

vheon commented Apr 17, 2015

@ekfriis will gocode tell us something if there are some error in the file? or it would just return an empty json?

@ekfriis
Copy link
Contributor

ekfriis commented Apr 17, 2015

Trying to do some completions on a garbage file, AFAICT it just returns an empty json. Is YCM expected to report compile errors? IMO I should change that RuntimeException to just return an empty set of completions.

@vheon
Copy link
Contributor

vheon commented Apr 17, 2015

@ekfriis I'm not sure that return an empty set will be an optimal choice, I mean: I write some_var. and expect the possible candidates and no error are shown nor the completion.

YCM report compile errors if the completion engine is able to provide some. If you write C/C++ you get compiler errors, if you write python then you don't get those, since jedi don't generate errors, @Valloric can correct me if I'm wrong.

@Valloric
Copy link
Member

@ekfriis If we know that we're not producing completions because of an error in the semantic engine, then we should report an error (by throwing an exception). See how the clang_completer handles it. YCM will then show that exception message in the Vim status area.

On the other hand, if we know that there really are no completions to be offered, no error should be shown. The clang_completer currently errs on the side of always showing the error message if it never gets completions but that's because it's extremely rare to encounter a situation where libclang truly doesn't have anything to show.

@cfsalguero
Copy link
Author

Hi,
Just wanted to say that this is hard to debug and I don't want to make you lose time with theory.
For example, after the last update (just now) I've noticed completion is slow displaying/choosing the list of options. I was writing Go code and upon writing http.Status, since that list is quite long, then it became slow.
Sorry for not being able to give you more accurate information.
For me, it is Ok if you close the thread.
I need syntastic more than the auto-completion so it is Ok.
Thank you anyways.

@oblitum
Copy link
Contributor

oblitum commented Apr 17, 2015

@cfsalguero have you checked vim-go? I use it with syntastic and YCM daily and it has more mileage. I'm not sure what's gonna happen when I update YCM, I guess just not building it with go-completer enabled will do the trick to keep my current setup.

@oblitum
Copy link
Contributor

oblitum commented Apr 17, 2015

@oblitum
Copy link
Contributor

oblitum commented Apr 17, 2015

At the time I've concluded syntastic default setup wasn't good enough or taken with care. There's a long discussion related with those one mentioned previously:

Hence, I've preferred to have more specific plugins than have active syntastic enabled.

@ekfriis
Copy link
Contributor

ekfriis commented Apr 17, 2015

Hi @oblitum,

For better or worse, if the gocode binary is on your path YCM will start using it to do Golang completion (and override the omnifunc which vim-go defines). @Valloric, do you think we should provide an override option? If we use the YCM blacklist option, will that kill the YCM omnifunc completion?

In principle the new YCM implementation should be categorically better in terms of latency. It would be great if you could give it a try and let me know if you find otherwise!

@cfsalguero
Copy link
Author

Even with syntastic disabled, YCM is imposible to use for me.
As I've mentioned, autocompetion on http.Status take ages to move the cursor just 1 line down.

@oblitum
Copy link
Contributor

oblitum commented Apr 17, 2015

In principle the new YCM implementation should be categorically better in terms of latency. It would be great if you could give it a try and let me know if you find otherwise!

@ekfriis Will do when I get some free-time. One thing is that I'm quite content with vim-go already, simply I have no latency, it was never a problem regardless of the packages I use, and my job machine is a very modest linux laptop.

@oblitum
Copy link
Contributor

oblitum commented Apr 17, 2015

@vheon Yeah, thanks. I've got double confirmation of that, so it seems I should be afraid of =[ ]

@vheon
Copy link
Contributor

vheon commented Apr 17, 2015

@Valloric could we do something like it is with clang completer? So checking if the user have set the appropriate flag in the build process?

@ekfriis
Copy link
Contributor

ekfriis commented Apr 17, 2015

@cfsalguero is it possible for you to share the code you are working on (or a minimal test case)?

@cfsalguero
Copy link
Author

I'll try to do it with an open source project I'm currently working on.

@Valloric
Copy link
Member

@vheon We could do it that way, sure.

@ekfriis
Copy link
Contributor

ekfriis commented Apr 19, 2015

Hi @cfsalguero,

Another thought - can you check what gocode binary you are using? If you look at the stderr file reported by :YcmDebugInfo at the top you should see a line like "Enabling go completion using [path to binary"

@cfsalguero
Copy link
Author

What I've found is that disabling vim-go t works a lot better.
Another thing I've found is that when vim-go is enabled, it becomes super slow just after opening a parenthesis
I'm using the gocode in my gopath. Which gocode returns /home/karl/golang/bin//gocode

@cfsalguero
Copy link
Author

Remember, I'm online with my email. Feel free to contact me on G+

@ekfriis
Copy link
Contributor

ekfriis commented Apr 23, 2015

Hi @cfsalguero, I tried to recreate the slowness w/ vim-go with this minimal vimrc (following the install instructions at gmarik/Vundle.vim, Valloric/YouCompleteMe, and fatih/vim-go, respectively) and doing completions in the nsf/gocode package, but it seems okay to me:

set nocompatible              " be iMproved, required
filetype off                  " required

" set the runtime path to include Vundle and initialize
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()

" let Vundle manage Vundle, required
Plugin 'gmarik/Vundle.vim'
Plugin 'Valloric/YouCompleteMe'
Plugin 'fatih/vim-go'

call vundle#end()            " required
filetype plugin indent on    " required
syntax on

Can you try with this setup and/or post your vimrc?

@cfsalguero
Copy link
Author

This is the link to my vimrc https://github.com/cfsalguero/vim_config

@cfsalguero
Copy link
Author

There is any irc channel to talk?
For example, I've updated my plugins today and now I have omni completion instead of gocode.
It is really frustrating not knowing if it is a configuration issue, if it is related to the plugins I have or what is happening

@ekfriis
Copy link
Contributor

ekfriis commented Apr 24, 2015

Hi @cfsalguero it is hard for me to communicate synchronously on IRC or equivalent - can you try the minimal vimrc above and see if you still have problems?

@cfsalguero
Copy link
Author

with the minimal version it works Ok

@ekfriis
Copy link
Contributor

ekfriis commented Apr 24, 2015

When I have a problem with my vimrc, I usually find the best way to debug
is to binary search - comment out half the vimrc, see if problem is still
there, recurse into that half, etc.

On Fri, Apr 24, 2015 at 9:50 AM Carlos Salguero notifications@github.com
wrote:

with the minimal version it works Ok


Reply to this email directly or view it on GitHub
#1461 (comment)
.

@cfsalguero
Copy link
Author

I did what you said, comment out most of my .vimrc and started over.
It works know and I disabled syntastic.
The only thing I miss is having the lines with errors marked in red in the gutter column.
There is any way of having that with YCM?
Other than that, I'm closing this issue
Thanks

@ekfriis
Copy link
Contributor

ekfriis commented Apr 24, 2015

Hi @cfsalguero, so what exactly were the lines that were bad in the end? If possible I would like it to work nicely with syntastic

@cfsalguero
Copy link
Author

just removed syntastic and all its configuration.
There is a link to my config in a previous msg

@vheon
Copy link
Contributor

vheon commented Apr 24, 2015

@cfsalguero so with only syntastic but no YCM you have no problem, with YCM and no syntastic you have no problem, but with syntastic and YCM you have a slow experience??

@cfsalguero
Copy link
Author

Really don't know what to say.
I can give you the steps I did:

  1. removed all plugins
  2. removed go
  3. reinstalled go
  4. started from the very basic config
  5. started to install 1 by 1
  6. disabled syntastic because it started to work slow again
    Those were my steps. For me is very annoying too.

@cfsalguero
Copy link
Author

Just as a comment, depending on the file I'm still have slowness so I decided to use just a plain vim

@vheon
Copy link
Contributor

vheon commented Apr 24, 2015

@cfsalguero if the project is Open Source could you share it?

@cfsalguero
Copy link
Author

Sadly, no

@cfsalguero
Copy link
Author

Hi again.
First I want to thank you for taking care of this. I know you work for free and I really appreciate it and I'm really thankful.
Second, I want to apologize for not being able to provide you with better information.
I did this in my vim to try to have more information:

:profile start profile.log
:profile func *
:profile file *
" At this point did slow actions
" for example, I have a line that says something like this
"Db.TruncateTables([]string{"table1", "table2", "table3", "table4"})
" and when I try to add a new table between quotes or I try to delete the quotes AND the text, the editor becomes unusable.
:profile pause

and this is the result in the log file. I hope it helps.
FUNCTION gitgutter#process_buffer()
Called 1 time
Total time: 0.000166
Self time: 0.000066

count total (s) self (s)
1 0.000032 0.000011 call gitgutter#utility#set_buffer(a:bufnr)
1 0.000081 0.000008 if gitgutter#utility#is_active()
1 0.000002 if g:gitgutter_sign_column_always
call gitgutter#sign#add_dummy_sign()
endif
1 0.000002 try
1 0.000013 0.000007 if !a:realtime || gitgutter#utility#has_fresh_changes()
let diff = gitgutter#diff#run_diff(a:realtime || gitgutter#utility#has_unsaved_changes(), 1)
call gitgutter#hunk#set_hunks(gitgutter#diff#parse_diff(diff))
let modified_lines = gitgutter#diff#process_hunks(gitgutter#hunk#hunks())

                                if len(modified_lines) > g:gitgutter_max_signs
                                  call gitgutter#utility#warn('exceeded maximum number of signs (configured by g:gitgutter_max_signs).')
                                  call gitgutter#sign#clear_signs()
                                  return
                                endif

                                if g:gitgutter_signs || g:gitgutter_highlight_lines
                                  call gitgutter#sign#update_signs(modified_lines)
                                endif

                                call gitgutter#utility#save_last_seen_change()
                              endif
1              0.000001     catch /diff failed/
                              call gitgutter#hunk#reset()
                            endtry
1              0.000001   else
                            call gitgutter#hunk#reset()
                          endif

FUNCTION 70_OnCursorMovedNormalMode()
Called 57 times
Total time: 0.048729
Self time: 0.007228

count total (s) self (s)
57 0.001823 0.000238 if !s:AllowedToCompleteInCurrentFile()
return
endif

57 0.040154 0.000238 call s:OnFileReadyToParse()
57 0.006591 py ycm_state.OnCursorMoved()

FUNCTION 70_UpdateDiagnosticNotifications()
Called 59 times
Total time: 0.000825
Self time: 0.000580

count total (s) self (s)
59 0.000640 0.000395 let should_display_diagnostics = g:ycm_show_diagnostics_ui && s:DiagnosticUiSupportedForCurrentFiletype() && pyeval( 'ycm_state.NativeFiletypeCompletionUsable()' )

59 0.000065 if !should_display_diagnostics
59 0.000040 return
endif

                          py ycm_state.UpdateDiagnosticInterface()

FUNCTION gitgutter#utility#not_git_dir()
Called 1 time
Total time: 0.000041
Self time: 0.000024

count total (s) self (s)
1 0.000040 0.000023 return gitgutter#utility#full_path_to_directory_of_file() !~ '[/].git($|[/])'

FUNCTION 70_SetUpCompleteopt()
Called 1 time
Total time: 0.000018
Self time: 0.000018

count total (s) self (s)
" Some plugins (I'm looking at you, vim-notes) change completeopt by for
" instance adding 'longest'. This breaks YCM. So we force our settings.
" There's no two ways about this: if you want to use YCM then you have to
" have these completeopt settings, otherwise YCM won't work at all.

                          " We need menuone in completeopt, otherwise when there's only one candidate
                          " for completion, the menu doesn't show up.
1              0.000006   set completeopt-=menu
1              0.000002   set completeopt+=menuone

                          " This is unnecessary with our features. People use this option to insert
                          " the common prefix of all the matches and then add more differentiating chars
                          " so that they can select a more specific match. With our features, they
                          " don't need to insert the prefix; they just type the differentiating chars.
                          " Also, having this option set breaks the plugin.
1              0.000002   set completeopt-=longest

1              0.000002   if g:ycm_add_preview_to_completeopt
                            set completeopt+=preview
                          endif

FUNCTION 70_UpdateCursorMoved()
Called 2 times
Total time: 0.000039
Self time: 0.000039

count total (s) self (s)
2 0.000017 let current_position = getpos('.')
2 0.000005 let s:cursor_moved = current_position != s:old_cursor_position

2              0.000009   let s:moved_vertically_in_insert_mode = s:old_cursor_position != [] && current_position[ 1 ] != s:old_cursor_position[ 1 ]

2              0.000004   let s:old_cursor_position = current_position

FUNCTION gitgutter#utility#set_buffer()
Called 1 time
Total time: 0.000021
Self time: 0.000021

count total (s) self (s)
1 0.000004 let s:bufnr = a:bufnr
1 0.000016 let s:file = resolve(bufname(a:bufnr))

FUNCTION 70_OnCursorHold()
Called 1 time
Total time: 0.000123
Self time: 0.000024

count total (s) self (s)
1 0.000037 0.000008 if !s:AllowedToCompleteInCurrentFile()
return
endif

1   0.000026   0.000008   call s:SetUpCompleteopt()
1   0.000059   0.000007   call s:OnFileReadyToParse()

FUNCTION 70_OnInsertLeave()
Called 1 time
Total time: 0.002644
Self time: 0.002558

count total (s) self (s)
1 0.000050 0.000009 if !s:AllowedToCompleteInCurrentFile()
return
endif

1              0.000003   let s:omnifunc_mode = 0
1   0.000050   0.000005   call s:OnFileReadyToParse()
1              0.002529   py ycm_state.OnInsertLeave()
1              0.000005   if g:ycm_autoclose_preview_window_after_completion || g:ycm_autoclose_preview_window_after_insertion
                            call s:ClosePreviewWindowIfNeeded()
                          endif

FUNCTION 58_Highlight_Matching_Pair()
Called 76 times
Total time: 0.013880
Self time: 0.013880

count total (s) self (s)
" Remove any previous match.
76 0.000591 if exists('w:paren_hl_on') && w:paren_hl_on
5 0.000018 3match none
5 0.000018 let w:paren_hl_on = 0
5 0.000008 endif

                          " Avoid that we remove the popup menu.
                          " Return when there are no colors (looks like the cursor jumps).

76 0.000398 if pumvisible() || (&t_Co < 8 && !has("gui_running"))
return
endif

                          " Get the character under the cursor and check if it's in 'matchpairs'.

76 0.000240 let c_lnum = line('.')
76 0.000212 let c_col = col('.')
76 0.000076 let before = 0

76 0.000401 let c = getline(c_lnum)[c_col - 1]
76 0.001166 let plist = split(&matchpairs, '.\zs[:,]')
76 0.000265 let i = index(plist, c)
76 0.000087 if i < 0
" not found, in Insert mode try character before the cursor
72 0.000247 if c_col > 1 && (mode() == 'i' || mode() == 'R')
2 0.000003 let before = 1
2 0.000006 let c = getline(c_lnum)[c_col - 2]
2 0.000006 let i = index(plist, c)
2 0.000001 endif
72 0.000065 if i < 0
" not found, nothing to do
71 0.000068 return
endif
1 0.000001 endif

                          " Figure out the arguments for searchpairpos().
5              0.000006   if i % 2 == 0
3              0.000004     let s_flags = 'nW'
3              0.000010     let c2 = plist[i + 1]
3              0.000003   else
2              0.000004     let s_flags = 'nbW'
2              0.000004     let c2 = c
2              0.000004     let c = plist[i - 1]
2              0.000001   endif
5              0.000009   if c == '['
2              0.000002     let c = '\['
2              0.000003     let c2 = '\]'
2              0.000001   endif

                          " Find the match.  When it was just before the cursor move it there for a
                          " moment.
5              0.000005   if before > 0
1              0.000004     let save_cursor = winsaveview()
1              0.000004     call cursor(c_lnum, c_col - before)
1              0.000000   endif

                          " When not in a string or comment ignore matches inside them.
                          " We match "escape" for special items, such as lispEscapeSpecial.
5              0.000019   let s_skip ='synIDattr(synID(line("."), col("."), 0), "name") ' . '=~?  "string\\|character\\|singlequote\\|escape\\|comment"'
5              0.005092   execute 'if' s_skip '| let s_skip = 0 | endif'

                          " Limit the search to lines visible in the window.
5              0.000017   let stoplinebottom = line('w$')
5              0.000012   let stoplinetop = line('w0')
5              0.000005   if i % 2 == 0
3              0.000005     let stopline = stoplinebottom
3              0.000002   else
2              0.000003     let stopline = stoplinetop
2              0.000002   endif

                          " Limit the search time to 300 msec to avoid a hang on very long lines.
                          " This fails when a timeout is not supported.
5              0.000011   if mode() == 'i' || mode() == 'R'
1              0.000003     let timeout = exists("b:matchparen_insert_timeout") ? b:matchparen_insert_timeout : g:matchparen_insert_timeout
1              0.000001   else
4              0.000019     let timeout = exists("b:matchparen_timeout") ? b:matchparen_timeout : g:matchparen_timeout
4              0.000001   endif
5              0.000012   try
5              0.002572     let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip, stopline, timeout)
5              0.000010   catch /E118/
                            " Can't use the timeout, restrict the stopline a bit more to avoid taking
                            " a long time on closed folds and long lines.
                            " The "viewable" variables give a range in which we can scroll while
                            " keeping the cursor at the same position.
                            " adjustedScrolloff accounts for very large numbers of scrolloff.
                            let adjustedScrolloff = min([&scrolloff, (line('w$') - line('w0')) / 2])
                            let bottom_viewable = min([line('$'), c_lnum + &lines - adjustedScrolloff - 2])
                            let top_viewable = max([1, c_lnum-&lines+adjustedScrolloff + 2])
                            " one of these stoplines will be adjusted below, but the current values are
                            " minimal boundaries within the current window
                            if i % 2 == 0
                              if has("byte_offset") && has("syntax_items") && &smc > 0
                            let stopbyte = min([line2byte("$"), line2byte(".") + col(".") + &smc * 2])
                            let stopline = min([bottom_viewable, byte2line(stopbyte)])
                              else
                            let stopline = min([bottom_viewable, c_lnum + 100])
                              endif
                              let stoplinebottom = stopline
                            else
                              if has("byte_offset") && has("syntax_items") && &smc > 0
                            let stopbyte = max([1, line2byte(".") + col(".") - &smc * 2])
                            let stopline = max([top_viewable, byte2line(stopbyte)])
                              else
                            let stopline = max([top_viewable, c_lnum - 100])
                              endif
                              let stoplinetop = stopline
                            endif
                            let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip, stopline)
                          endtry

5              0.000007   if before > 0
1              0.000017     call winrestview(save_cursor)
1              0.000001   endif

                          " If a match is found setup match highlighting.
5              0.000014   if m_lnum > 0 && m_lnum >= stoplinetop && m_lnum <= stoplinebottom 
5              0.000122     exe '3match MatchParen /\(\%' . c_lnum . 'l\%' . (c_col - before) . 'c\)\|\(\%' . m_lnum . 'l\%' . m_col . 'c\)/'
5              0.000009     let w:paren_hl_on = 1
5              0.000005   endif

FUNCTION gitgutter#utility#has_fresh_changes()
Called 1 time
Total time: 0.000006
Self time: 0.000006

count total (s) self (s)
1 0.000005 return getbufvar(s:bufnr, 'changedtick') != getbufvar(s:bufnr, 'gitgutter_last_tick')

FUNCTION 70_AllowedToCompleteInCurrentFile()
Called 62 times
Total time: 0.001760
Self time: 0.001760

count total (s) self (s)
62 0.000616 if empty( &filetype ) || getbufvar( winbufnr( winnr() ), "&buftype" ) ==# 'nofile' || &filetype ==# 'qf'
return 0
endif

62 0.000140 if exists( 'b:ycm_largefile' )
return 0
endif

62 0.000339 let whitelist_allows = has_key( g:ycm_filetype_whitelist, '*' ) || has_key( g:ycm_filetype_whitelist, &filetype )
62 0.000199 let blacklist_allows = !has_key( g:ycm_filetype_blacklist, &filetype )

62 0.000116 return whitelist_allows && blacklist_allows

FUNCTION 70_OnInsertEnter()
Called 1 time
Total time: 0.000054
Self time: 0.000014

count total (s) self (s)
1 0.000047 0.000007 if !s:AllowedToCompleteInCurrentFile()
return
endif

1              0.000003   let s:old_cursor_position = []

FUNCTION 70_SetUpYcmChangedTick()
Called 59 times
Total time: 0.000372
Self time: 0.000372

count total (s) self (s)
59 0.000349 let b:ycm_changedtick = get( b:, 'ycm_changedtick', { 'file_ready_to_parse' : -1, } )

FUNCTION gitgutter#utility#full_path_to_directory_of_file()
Called 1 time
Total time: 0.000017
Self time: 0.000017

count total (s) self (s)
1 0.000016 return fnamemodify(s:file, ':p:h')

FUNCTION 70_OnFileReadyToParse()
Called 59 times
Total time: 0.040013
Self time: 0.038816

count total (s) self (s)
" We need to call this just in case there is no b:ycm_changetick; this can
" happen for special buffers.
59 0.000589 0.000217 call s:SetUpYcmChangedTick()

                          " Order is important here; we need to extract any done diagnostics before
                          " reparsing the file again. If we sent the new parse request first, then
                          " the response would always be pending when we called
                          " UpdateDiagnosticNotifications.

59 0.001046 0.000221 call s:UpdateDiagnosticNotifications()

59 0.000171 let buffer_changed = b:changedtick != b:ycm_changedtick.file_ready_to_parse
59 0.000056 if buffer_changed
17 0.037587 py ycm_state.OnFileReadyToParse()
17 0.000033 endif
59 0.000169 let b:ycm_changedtick.file_ready_to_parse = b:changedtick

FUNCTION gitgutter#utility#exists_file()
Called 1 time
Total time: 0.000018
Self time: 0.000018

count total (s) self (s)
1 0.000018 return filereadable(s:file)

FUNCTION 70_BufferTextChangedSinceLastMoveInInsertMode()
Called 2 times
Total time: 0.000024
Self time: 0.000024

count total (s) self (s)
2 0.000002 if s:moved_vertically_in_insert_mode
1 0.000002 let s:previous_num_chars_on_current_line = -1
1 0.000001 return 0
endif

1              0.000003   let num_chars_in_current_cursor_line = strlen( getline('.') )

1              0.000002   if s:previous_num_chars_on_current_line == -1
                            let s:previous_num_chars_on_current_line = num_chars_in_current_cursor_line
                            return 0
                          endif

1              0.000003   let changed_text_on_current_line = num_chars_in_current_cursor_line != s:previous_num_chars_on_current_line
1              0.000002   let s:previous_num_chars_on_current_line = num_chars_in_current_cursor_line

1              0.000001   return changed_text_on_current_line

FUNCTION gitgutter#utility#is_active()
Called 1 time
Total time: 0.000073
Self time: 0.000014

count total (s) self (s)
1 0.000072 0.000013 return g:gitgutter_enabled && gitgutter#utility#exists_file() && gitgutter#utility#not_git_dir()

FUNCTION 70_DiagnosticUiSupportedForCurrentFiletype()
Called 59 times
Total time: 0.000245
Self time: 0.000245

count total (s) self (s)
59 0.000205 return get( s:diagnostic_ui_filetypes, &filetype, 0 )

FUNCTION 70_OnCursorMovedInsertMode()
Called 2 times
Total time: 0.000391
Self time: 0.000263

count total (s) self (s)
2 0.000074 0.000009 if !s:AllowedToCompleteInCurrentFile()
return
endif

2              0.000220   py ycm_state.OnCursorMoved()
2   0.000051   0.000012   call s:UpdateCursorMoved()

                          " Basically, we need to only trigger the completion menu when the user has
                          " inserted or deleted a character, NOT just when the user moves in insert mode
                          " (with, say, the arrow keys). If we trigger the menu even on pure moves, then
                          " it's impossible to move in insert mode since the up/down arrows start moving
                          " the selected completion in the completion menu. Yeah, people shouldn't be
                          " moving in insert mode at all (that's what normal mode is for) but explain
                          " that to the users who complain...
2   0.000034   0.000010   if !s:BufferTextChangedSinceLastMoveInInsertMode()
2              0.000001     return
                          endif

                          call s:IdentifierFinishedOperations()
                          if g:ycm_autoclose_preview_window_after_completion
                            call s:ClosePreviewWindowIfNeeded()
                          endif

                          if g:ycm_auto_trigger || s:omnifunc_mode
                            call s:InvokeCompletion()
                          endif

                          " We have to make sure we correctly leave omnifunc mode even when the user
                          " inserts something like a "operator[]" candidate string which fails
                          " CurrentIdentifierFinished check.
                          if s:omnifunc_mode && !pyeval( 'base.LastEnteredCharIsIdentifierChar()')
                            let s:omnifunc_mode = 0
                          endif

FUNCTIONS SORTED ON TOTAL TIME
count total (s) self (s) function
57 0.048729 0.007228 70_OnCursorMovedNormalMode()
59 0.040013 0.038816 70_OnFileReadyToParse()
76 0.013880 58_Highlight_Matching_Pair()
1 0.002644 0.002558 70_OnInsertLeave()
62 0.001760 70_AllowedToCompleteInCurrentFile()
59 0.000825 0.000580 70_UpdateDiagnosticNotifications()
2 0.000391 0.000263 70_OnCursorMovedInsertMode()
59 0.000372 70_SetUpYcmChangedTick()
59 0.000245 70_DiagnosticUiSupportedForCurrentFiletype()
1 0.000166 0.000066 gitgutter#process_buffer()
1 0.000123 0.000024 70_OnCursorHold()
1 0.000073 0.000014 gitgutter#utility#is_active()
1 0.000054 0.000014 70_OnInsertEnter()
1 0.000041 0.000024 gitgutter#utility#not_git_dir()
2 0.000039 70_UpdateCursorMoved()
2 0.000024 70_BufferTextChangedSinceLastMoveInInsertMode()
1 0.000021 gitgutter#utility#set_buffer()
1 0.000018 70_SetUpCompleteopt()
1 0.000018 gitgutter#utility#exists_file()
1 0.000017 gitgutter#utility#full_path_to_directory_of_file()

FUNCTIONS SORTED ON SELF TIME
count total (s) self (s) function
59 0.040013 0.038816 70_OnFileReadyToParse()
76 0.013880 58_Highlight_Matching_Pair()
57 0.048729 0.007228 70_OnCursorMovedNormalMode()
1 0.002644 0.002558 70_OnInsertLeave()
62 0.001760 70_AllowedToCompleteInCurrentFile()
59 0.000825 0.000580 70_UpdateDiagnosticNotifications()
59 0.000372 70_SetUpYcmChangedTick()
2 0.000391 0.000263 70_OnCursorMovedInsertMode()
59 0.000245 70_DiagnosticUiSupportedForCurrentFiletype()
1 0.000166 0.000066 gitgutter#process_buffer()
2 0.000039 70_UpdateCursorMoved()
1 0.000123 0.000024 70_OnCursorHold()
1 0.000041 0.000024 gitgutter#utility#not_git_dir()
2 0.000024 70_BufferTextChangedSinceLastMoveInInsertMode()
1 0.000021 gitgutter#utility#set_buffer()
1 0.000018 70_SetUpCompleteopt()
1 0.000018 gitgutter#utility#exists_file()
1 0.000017 gitgutter#utility#full_path_to_directory_of_file()
1 0.000073 0.000014 gitgutter#utility#is_active()
1 0.000054 0.000014 70_OnInsertEnter()

@oblitum
Copy link
Contributor

oblitum commented May 10, 2015

@ekfriis so, I've tried it on OS X and even though it's overriding vim-go, I'm not seeing any issues. I think I'll stick with this setup, YCM overrides completion but I still take the rest from vim-go without issues I hope. Thanks!

@oblitum
Copy link
Contributor

oblitum commented May 10, 2015

@ekfriis I've one concern though. Compared to other completion options even on YCM, the one built into YCM for golang is putting function prototype information at the type, instead of directly at the completion text. It looks like non conventional.

@ekfriis
Copy link
Contributor

ekfriis commented May 11, 2015

Hi @oblitum, glad to hear it is working for you. I'm not totally sure I understand your suggestion, can you give an example of what you think the completion should look like?

@cfsalguero sorry, just realized this fell off my stack. Looking at your profile, it seems the slowest functions are:

57 0.048729 0.007228 70_OnCursorMovedNormalMode()
59 0.040013 0.038816 70_OnFileReadyToParse()
76 0.013880 58_Highlight_Matching_Pair()

@Valloric, it looks like it is spending a lot of time in OnFileReadyToParse - is this normal? As far as I can tell, that is for the omnifunc(?), which should not be called at all in Go w/ the latest YCM.

@vheon
Copy link
Contributor

vheon commented May 11, 2015

@ekfriis OnFileReadyToParse the client send the buffer to the server, so ycmd is able to pick up new candidates for the identifier-based engine, and the server would also call the same function on the current semantic completer if it defines said function but the gocode completer does not.

@oblitum
Copy link
Contributor

oblitum commented May 11, 2015

Hi @ekfriis, for example, you may check the C and C++ completion that's displayed by the GIF in the official README, BUT, I think it's not a big issue, since it's not a standard followed by all languages.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 9, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants