Ответ на сообщение «Re: Progress indicator for :TOhtml command», 
присланное в 10:59:42 06 июня 2010, Воскресенье,
отправитель Benjamin Fritz:

It is odd: the only problem in your script is redrawstatus which is called only 
100 times (without styles, 109 with) (>21 seconds), while in my script 
redrawstatus called 328 times takes less than a second.

Second problem with the whole 2html is buffer switching, I think you should 
consider instead of doing constant switches, save every line in a List and only 
after everything is finished create a new buffer and call setline(1, s:list). 
Note that new versions of my script are faster (but not much) then your 2html 
because I use this technique.

And, why do you calculate length of the title at each progressbarupdate? 
Attached patch fixes this and the case when there is no space for progress bar. 

Текст сообщения:
> On Jun 5, 8:10 pm, ZyX <zyx....@gmail.com> wrote:
> > It occures that the problem is not floating-point math: the attached
> > patch removes this math but does not add any perfomance.
> 
> Yes, I did not expect any performance gains from removing the little
> bit of remaining floating point, since it is just up to 100
> calculations done once at the start and thereafter only when the
> window changes size. It is a good idea to remove, because as you point
> out, that amount of precision is probably unnecessary, and it would
> just introduce another dependency.
> 
> > It also removes recalculating
> > progress bar width (you just used used some generic progress bar?) and
> > needs_redraw.
> 
> Yes, we did use a generic progress bar as the starting point for this.
> However, I think it IS necessary to recalculate the progress bar
> width. This is done so that if the user changes window sizes, the
> progress bar will be updated accordingly. We don't want a progress bar
> that is too big to fit in the window, or smaller than needed for
> decent viewing. With your patch, if you start with the gvim window
> maximized, then restore the window to a smaller size, Vim goes blank
> until the next progress bar update, and then the progress bar is too
> large to fit on the screen and is truncated. This is not desirable,
> but perhaps it would acceptable if the performance gains are great
> enough. This does not seem to be the case, because I added back in the
> size recalculation with no noticeable performance hit.
> 
> The needs_redraw was done in order to allow us to call redrawstatus on
> the correct window. :help redrawstatus says that it redraws the status
> line for the *current window* only unless you use redrawstatus! which
> redraws all windows. In practice, however, it does not seem to matter
> which window we use it in. Why is this?
> 
> > Also, why you forbid profiling progress bar functions? It is also
> > fixed.
> 
> Good catch, that's certainly something to include going forward.
> 
> There is a slight speed gain from your patch, however there is a
> mistaken assumption in the way you update the progress bar. Your code
> assumes that the progress bar will only ever update by one tick at a
> time. Updating the progress bar without your patch calculates the
> entire string every time, using repeat(). Your update simply adds one
> to the colored string of spaces, and subtracts one from the uncolored.
> This does not work if the user folds away some text and does not use
> dynamic folding, it does not work when there are fewer than 100 lines
> in the text to convert, and it does not work for the second use of the
> progress bar, where there are usually fewer that 100 highlight groups
> to process.
> 
> I corrected this problem and initially, the performance still seemed
> to be improved over the previous version. However, I noticed afterward
> that part of the patch removes the "sleep 100m" from the "processing
> classes" step. I took this line out of the original script for a fair
> comparison, and got the following timings, converting
> autoload/netrw.vim (7764 lines) with dynamic folding enabled:
> 
> Before patch: 50 seconds
> Patch from ZyX: 49 seconds
> Fixed patch: 51 seconds
> 
> So, it looks like the patch is actually no faster, and potentially
> slightly slower than the precalculated version.
> 
> I have therefore attached an updated version of my last submission,
> which removes floating point from the calculate_ticks function, and
> incorporates some of the other improvements from ZyX.
> 
> This version takes 50 seconds to convert netrw, if I comment out the
> sleep 100 line. Do we want this line in the code? Without it, if there
> are not very many highlight groups to process, the "processing
> classes" bar flashes by without being seen. This happens anyway for
> very small selections. I don't know how I feel about deliberately
> slowing down the execution. I have left it commented out for now.
> 
> I am very curious about this:
> 
> " Note that you must use len(split) instead of len() if you want to use
> " unicode in title
> let self.pb_len = max_len-len(split(self.title, '\zs'))-3-4-2
> 
> Can someone explain the problem described in the comment a little
> better? And why does the split on '\zs' work to fix the problem?
> 
--- oldnew2html.vim	2010-06-06 12:24:39.000000000 +0400
+++ 2html.vim	2010-06-06 12:23:17.000000000 +0400
@@ -561,4 +561,11 @@
 		let pgb.last_value = 0
 		let pgb.needs_redraw = 0
+		" Note that you must use len(split) instead of len() if you want to use 
+		" unicode in title.
+		"
+		" Subtract 3 for spacing around the title.
+		" Subtract 4 for the percentage display.
+		" Subtract 2 for spacing before this.
+		let pgb.substractedlen=len(split(pgb.title, '\zs'))+3+4+2
 		let pgb.max_len = 0
 		set laststatus=2
@@ -568,5 +575,10 @@
 	" Function: progressbar.calculate_ticks() {{{1
 	func! s:progressbar.calculate_ticks(pb_len)
-		let self.progress_ticks = map(range(a:pb_len+1), "v:val * self.max_value / a:pb_len")
+		if a:pb_len<=0
+			let pb_len = 100
+		else
+			let pb_len = a:pb_len
+		endif
+		let self.progress_ticks = map(range(pb_len+1), "v:val * self.max_value / pb_len")
 	endfun
 
@@ -581,11 +593,5 @@
 
 			" Progressbar length
-			" Note that you must use len(split) instead of len() if you want to use 
-			" unicode in title.
-			"
-			" Subtract 3 for spacing around the title.
-			" Subtract 4 for the percentage display.
-			" Subtract 2 for spacing before this.
-			let pb_len = max_len-len(split(self.title, '\zs'))-3-4-2
+			let pb_len = max_len - self.substractedlen
 			let pb_len = pb_len > 100 ? 100 : pb_len
 
@@ -601,6 +607,8 @@
 		endif
 
+		let cur_val_max = pb_len > 0 ? pb_len : 100
+
 		" find the current progress bar position based on precalculated thresholds
-		while cur_value < pb_len && self.cur_value > self.progress_ticks[cur_value]
+		while cur_value < cur_val_max && self.cur_value > self.progress_ticks[cur_value]
 			let cur_value += 1
 		endwhile
@@ -617,7 +625,9 @@
 
 			let stl =  "%#".t_color."#%-( ".self.title." %)".
-						\"%#".b_color."#|".
-						\"%#".b_fcolor."#%-(".repeat(" ",cur_value)."%)".
-						\"%#".b_color."#".repeat(" ",pb_len-cur_value)."|".
+						\"%#".b_color."#".
+						\(pb_len>0 ?
+						\	('|%#'.b_fcolor."#%-(".repeat(" ",cur_value)."%)".
+						\	 '%#'.b_color."#".repeat(" ",pb_len-cur_value)."|"):
+						\	('')).
 						\"%=%#".c_color."#%( ".printf("%3.d ",100*self.cur_value/self.max_value)."%% %)"
 			call setwinvar(self.winnr, '&stl', stl)

Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to