Ответ на сообщение «Re: Progress indicator for :TOhtml command», присланное в 19:39:15 05 июня 2010, Суббота, отправитель Benjamin Fritz:
It occures that the problem is not floating-point math: the attached patch removes this math but does not add any perfomance. It also removes recalculating progress bar width (you just used used some generic progress bar?) and needs_redraw. Also, why you forbid profiling progress bar functions? It is also fixed. Текст сообщения: > On Thu, Jun 3, 2010 at 10:03 PM, Benjamin Fritz <[email protected]> wrote: > > This version is still not fast enough though. It is about 30% slower > > when the progress bar is enabled than when it is disabled. While I > > consider it a good tradeoff in most cases, we could certainly make it > > better. > > > > It would probably be faster to pre-calculate the line numbers needed > > to advance the progress bar rather than doing a bunch of > > floating-point math every cycle. > > I've attached a new version which pre-calculates the (integer) line > numbers needed to advance the progress bar. Now all the floating point > math is done once, up front. > > The difference is not really very perceptible. I timed the execution > on two files. First, I did the 5148-line autoload/phpcomplete.vim > script. Timings were as follows on my laptop: > > progress disabled: > average: 46 seconds > > floating-point progress: > average: 61 seconds > slowdown: 15 seconds longer than without progress bar > percentage: 33% longer than without progress bar > > precalculated progress: > average: 62 seconds > slowdown: 16 seconds longer than without progress bar > percentage: 35% longer than without progress bar > > Next I did a 33258-line C code file: > > progress disabled: > average: 691 seconds > > floating-point progress: > average: 716 seconds > slowdown: 25 seconds longer than without progress bar > percentage: 4% longer than without progress bar > > precalculated progress: > average: 711 seconds > slowdown: 20 seconds longer than without progress bar > percentage: 3% longer than without progress bar > > I also did a number of very small sections of files (my usual use case > for 2html) and did not notice any significant slowing; it only takes > 1-2 seconds longer for a 100 or 200 line selection. > > I take a few things from this. > > First of all, I don't think we'll get much performance improvement > with this method. I do not know whether it is setting the status line > and redrawing it, or whether it is the use of the object-oriented > style functions, but it would probably require a different approach to > get a significant speedup. I certainly like the look a lot better than > the echo method, even if we could get echon working. Is a 10-20 second > slow-down acceptable on large numbers of lines, if the normal > execution time is measured in minutes anyway? To me, it certainly is. > If something is going to be taking more than a few minutes, I want a > progress bar to tell me whether it's worth letting it continue. Since > the slow-down can be significant for midsize files, we will certainly > need to mention in the :help that disabling the progress bar will make > the conversion faster. Maybe we should only show the progress bar > after some amount of time has elapsed? We could suppress the > redrawstatus until 10 seconds have passed, or something like that. Any > thoughts? > > Secondly, the precalculated version is not really any faster than the > full floating-point calculation every cycle. I don't really have an > opinion of which method gives more readable code. Does anyone else > have any opinions on which version to keep? I think it would be > possible to do away with floating point calculations entirely using > the precalculated version; currently floating point is only used in > the calculate_ticks function. This might be desireable so that we can > remove the dependence on the +float feature, which is not marked with > a "smallest version" indicator in :help +feature-list. This apparently > means it is "system dependent". Does this mean float is pretty much > always included, unless it is explicitly removed? How common are Vims > without floating-point support? I already added use of the split() > function, which was added in version 7, so this won't work on really > old Vims...but do we want to support Vim 7.1 and earlier? >
--- oldnew2html.vim 2010-06-06 03:33:44.000000000 +0400
+++ 2html.vim 2010-06-06 04:30:37.000000000 +0400
@@ -545,5 +545,5 @@
" set up progress bar in the status line
-if !s:html_no_progress && has("statusline") && has("float")
+if !s:html_no_progress && has("statusline")
" ProgressBar Indicator
let s:progressbar={}
@@ -559,50 +559,36 @@
\'bar' : { 'color' : 'Statusline' , 'fillcolor' : 'DiffDelete' , 'bg' : 'Statusline' } ,
\'counter' : { 'color' : 'Statusline' } }
- let pgb.last_value = 0
- let pgb.needs_redraw = 0
- let pgb.max_len = 0
+ let pgb.max_len = winwidth(pgb.winnr)-2
+ " Note that you must use len(split) instead of len() if you want to use
+ " unicode in title
+ let pgb.pb_len = pgb.max_len-len(split(pgb.title, '\zs'))-3-4-2
+ if pgb.pb_len<0
+ let pbg.pb_len=0
+ elseif pgb.pb_len>100
+ let pgb.pb_len=100
+ endif
+ let pgb.pb_startstr = ""
+ let pgb.pb_endstr = repeat(" ", pgb.pb_len)
+ let pgb.last_progresslen=-1
+ let pgb.last_percents=-1
set laststatus=2
return pgb
endfun
- " Function: progressbar.calculate_ticks() {{{1
- func! s:progressbar.calculate_ticks(pb_len)
- let tick = self.max_value / str2float(a:pb_len)
- let self.progress_ticks = map(range(a:pb_len+1), "float2nr(v:val * tick)")
- endfun
-
"Function: progressbar.paint()
func! s:progressbar.paint()
- " Recalculate widths
- let max_len = winwidth(self.winnr) - 2
- " Title length
- let t_len = strlen(self.title) + 3 " add offset for additional spaces
- " Counter length
- "let c_len = 2*strlen(self.max_value)+1
- let c_len = 4
- " Progressbar length
- let pb_len = max_len - t_len - c_len - 2
- let pb_len = pb_len > 100 ? 100 : pb_len
-
- " always true on first call because of initial value of self.max_len
- if max_len != self.max_len
- call self.calculate_ticks(pb_len)
- let self.needs_redraw = 1
- let cur_value = 0
- let self.max_len = max_len
- else
- " start searching at the last found index to make the search for the
- " appropriate tick value normally take 0 or 1 comparisons
- let cur_value = self.last_value
- endif
-
- while cur_value < pb_len && self.cur_value > self.progress_ticks[cur_value]
- let cur_value += 1
- endwhile
-
- if self.last_value != cur_value || self.needs_redraw
- let self.needs_redraw = 1
- let self.last_value = cur_value
-
+ let progresslen=self.pb_len*self.cur_value/self.max_value
+ let percents=100*self.cur_value/self.max_value
+ if progresslen!=self.last_progresslen || percents!=self.last_percents
+ if progresslen!=self.last_progresslen
+ let self.pb_startstr.=" "
+ let self.pb_endstr=self.pb_endstr[1:]
+ let self.last_progresslen=progresslen
+ endif
+ if percents!=self.last_percents
+ let self.last_percents=percents
+ let percents.=""
+ let self.percent_str=repeat(" ", 3-len(percents)).percents
+ endif
let t_color = self.items.title.color
let b_fcolor = self.items.bar.fillcolor
@@ -612,8 +598,9 @@
let stl = "%#".t_color."#%-( ".self.title." %)".
\"%#".b_color."#|".
- \"%#".b_fcolor."#%-(".repeat(" ",cur_value)."%)".
- \"%#".b_color."#".repeat(" ",pb_len-cur_value)."|".
- \"%=%#".c_color."#%( ".printf("%3.d ",100*self.cur_value/self.max_value)."%% %)"
+ \"%#".b_fcolor."#%-(".self.pb_startstr."%)".
+ \"%#".b_color."#".self.pb_endstr."|".
+ \"%=%#".c_color."#%( ".self.percent_str."%% %)"
call setwinvar(self.winnr, '&stl', stl)
+ redrawstatus
endif
@@ -876,8 +863,4 @@
exe s:newwin . "wincmd w"
exe "normal! a" . s:new . s:HtmlEndline . "\n\e"
- if !s:html_no_progress && s:pgb.needs_redraw
- redrawstatus
- let s:pgb.needs_redraw = 0
- endif
exe s:orgwin . "wincmd w"
let s:lnum = s:lnum + 1
@@ -987,9 +970,5 @@
if !s:html_no_progress
call s:pgb.incr()
- sleep 100m
- if s:pgb.needs_redraw
- redrawstatus
- let s:pgb.needs_redraw = 0
- endif
+ " sleep 100m
endif
endwhile
@@ -1055,18 +1034,19 @@
delfunc s:HtmlClosing
endif
-endif
-unlet! s:new_lnum s:diffattr s:difffillchar s:foldfillchar s:HtmlSpace s:LeadingSpace s:HtmlEndline s:firstfold s:foldcolumn
-unlet s:foldstack s:allfolds s:foldId s:numcol
-if exists("s:html_dynamic_folds")
- delfunc s:FoldCompare
-endif
+ if exists("s:html_dynamic_folds")
+ delfunc s:FoldCompare
+ endif
+
+ if !s:html_no_progress
+ delfunc s:ProgressBar
+ delfunc s:progressbar.paint
+ delfunc s:progressbar.incr
+ unlet s:pgb s:progressbar
+ endif
-if !s:html_no_progress
- delfunc s:ProgressBar
- delfunc s:progressbar.paint
- delfunc s:progressbar.incr
- unlet s:pgb s:progressbar
endif
+unlet! s:new_lnum s:diffattr s:difffillchar s:foldfillchar s:HtmlSpace s:LeadingSpace s:HtmlEndline s:firstfold s:foldcolumn
+unlet s:foldstack s:allfolds s:foldId s:numcol
unlet! s:html_no_progress s:html_dynamic_folds s:html_hover_unfold s:html_use_css
signature.asc
Description: This is a digitally signed message part.
