Hi,

On Sat, May 7, 2016 at 2:42 PM, Ramel Eshed <[email protected]> wrote:
> Hi All,
>
> Thanks to Bram and his recent work on channels, I have a preliminary
> version of an asynchronous grep plugin which lets you work with the
> available results while grep is still running. I would like to take
> advantage of this relatively short script to raise some issues and
> thoughts I have. The plugin can be found at
> https://github.com/ramele/agrep.
>

> 2. Quickfix issues
> a.    As long as there are not too many matches and
> the quickfix window is closed you can fire up a search and start
> jumping to the available matches while the search is still running
> using the quickfix navigation commands (:cn, for example). The problem
> is when the quickfix window is opened while the search is active –
> here there is a serious performance issue, and Vim hangs for a while.
> You can see this by running :copen and then :Agrep. Choose a search
> that will generate many results (> 1000).
>
> b.    As the matches rate becomes higher, Vim will become
> unresponsive. It may happen for short intervals or it can hangs for a
> while (for very high rate). By “rate” I simply mean to
> number_of_matches / sec. To compare, the performance is much better
> with the agrep window.
>
> As I understand (and please correct me if I’m wrong) when using
> setqflist() to create a new list or add items to the current list, Vim
> reads all the buffers (as an unlisted buffers) in order to set the
> hidden marks. I think that this is the reason of the slowness I’m
> experiencing. If I'm right, maybe the way Vim loads the buffers of the
> qf list should be changed so buffers will be loaded only when they're
> been accessed and not when they're added to the list. What do you
> think?
>

When adding a new entry to the quickfix list, a search is made to locate
the last entry. I think, this is the reason for the long processing time.
To confirm this, I created a test script to add 100000 entries to the
quickfix list. It took almost 120 seconds to complete. After I changed
the quickfix code to keep track of the last entry, this reduced to 2 seconds.
Can you try using the attached patch?

- Yegappan

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/quickfix.c b/src/quickfix.c
index a719e4f..3a9adaa 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -52,6 +52,7 @@ struct qfline_S
 typedef struct qf_list_S
 {
     qfline_T   *qf_start;      /* pointer to the first error */
+    qfline_T   *qf_last;       /* pointer to the last error */
     qfline_T   *qf_ptr;        /* pointer to the current error */
     int                qf_count;       /* number of errors (0 means no error 
list) */
     int                qf_index;       /* current index in the error list */
@@ -304,10 +305,10 @@ qf_init_ext(
        /* make place for a new list */
        qf_new_list(qi, qf_title);
     else if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
+    {
        /* Adding to existing list, find last entry. */
-       for (qfprev = qi->qf_lists[qi->qf_curlist].qf_start;
-                         qfprev->qf_next != qfprev; qfprev = qfprev->qf_next)
-           ;
+       qfprev = qi->qf_lists[qi->qf_curlist].qf_last;
+    }
 
 /*
  * Each part of the format string is copied and modified from errorformat to
@@ -1209,6 +1210,7 @@ qf_add_entry(
        (*prevp)->qf_next = qfp;
     }
     qfp->qf_next = qfp;        /* last element points to itself */
+    qi->qf_lists[qi->qf_curlist].qf_last = qfp;
     qfp->qf_cleared = FALSE;
     *prevp = qfp;
     ++qi->qf_lists[qi->qf_curlist].qf_count;
@@ -1308,6 +1310,7 @@ copy_loclist(win_T *from, win_T *to)
        to_qfl->qf_count = 0;
        to_qfl->qf_index = 0;
        to_qfl->qf_start = NULL;
+       to_qfl->qf_last = NULL;
        to_qfl->qf_ptr = NULL;
        if (from_qfl->qf_title != NULL)
            to_qfl->qf_title = vim_strsave(from_qfl->qf_title);
@@ -2381,6 +2384,7 @@ qf_free(qf_info_T *qi, int idx)
     vim_free(qi->qf_lists[idx].qf_title);
     qi->qf_lists[idx].qf_title = NULL;
     qi->qf_lists[idx].qf_index = 0;
+    qi->qf_lists[idx].qf_last = NULL;
 }
 
 /*
@@ -3618,9 +3622,7 @@ ex_vimgrep(exarg_T *eap)
        qf_new_list(qi, title != NULL ? title : *eap->cmdlinep);
     else if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
        /* Adding to existing list, find last entry. */
-       for (prevp = qi->qf_lists[qi->qf_curlist].qf_start;
-                           prevp->qf_next != prevp; prevp = prevp->qf_next)
-           ;
+       prevp = qi->qf_lists[qi->qf_curlist].qf_last;
 
     /* parse the list of arguments */
     if (get_arglist_exp(p, &fcount, &fnames, TRUE) == FAIL)
@@ -4210,9 +4212,7 @@ set_errorlist(
        qf_new_list(qi, title);
     else if (action == 'a' && qi->qf_lists[qi->qf_curlist].qf_count > 0)
        /* Adding to existing list, find last entry. */
-       for (prevp = qi->qf_lists[qi->qf_curlist].qf_start;
-            prevp->qf_next != prevp; prevp = prevp->qf_next)
-           ;
+       prevp = qi->qf_lists[qi->qf_curlist].qf_last;
     else if (action == 'r')
     {
        qf_free(qi, qi->qf_curlist);

Raspunde prin e-mail lui