Wikia

Vim Tips Wiki

Changes: Measure time taken to execute a command

Edit

Back to page

(Change <tt> to <code>, perhaps also minor tweak.)
(Replaced content with "select count(*) from apers P, asubject s where p.apnum = s.apnum and p.cschool = s.cschool;")
Line 1: Line 1:
{{review}}
+
select count(*) from apers P, asubject s
{{TipImported
+
where p.apnum = s.apnum
|id=1164
+
and p.cschool = s.cschool;
|previous=1161
 
|next=1166
 
|created=2006
 
|complexity=intermediate
 
|author=Salman Halim
 
|version=6.0
 
|rating=3/3
 
|category1=
 
|category2=
 
}}
 
Here is a function to determine how long something takes to execute – it's useful for determining which of a number of ways of doing something is faster.
 
 
Sample call: <code>echo HowLong("echo 'test'", 100)</code>
 
 
This will execute "<code>echo 'test'</code>" 100 times and display the number of seconds it took to do so.
 
 
Multiple commands can be separated by a <code>|</code>.
 
<pre>
 
" Times the number of times a particular command takes to execute the specified number of times (in seconds).
 
function! HowLong( command, numberOfTimes )
 
" We don't want to be prompted by a message if the command being tried is
 
" an echo as that would slow things down while waiting for user input.
 
let more = &more
 
set nomore
 
let startTime = localtime()
 
for i in range( a:numberOfTimes )
 
execute a:command
 
endfor
 
let result = localtime() - startTime
 
let &more = more
 
return result
 
endfunction
 
</pre>
 
 
==Comments==
 
What is it intended for? Wouldn't it be more reliable to use build-in profiling functionality for tuning purposes?
 
 
----
 
No doubt, but internal profiling requires a HUGE compilation, which isn't the default on Windows (BIG is). The biggest reason why I wrote this at all was that there was a function I used all the time that recently made it into the latest Vim 7 build, potentially making mine redundant. However, the internal one LOOKED like it was actually doing more work than was necessary, so I ran this method on a large number of iterations of the function call. Certainly, it wasn't anywhere near as accurate as using the internal profiling (for one thing, it can only provide accuracy to the second), but it was sufficient to indicate which way was faster.
 
 
----
 
Here's the function I use:
 
<pre>
 
function! Time(com, ...)
 
let time = 0.0
 
let numberOfTimes = a:0 ? a:1 : 50000
 
for i in range(numberOfTimes + 1)
 
let t = reltime()
 
execute a:com
 
let time += reltime(t)[1]
 
echo i.' / '.numberOfTimes
 
redraw
 
endfor
 
echo 'Average time: '.string(numberOfTimes / i)
 
endfunction
 
</pre>
 
 
==Timing a search==
 
:''The following has been moved here from [[VimTip516]]; it needs a clean up.''
 
 
I wanted to test how quickly various searches are. I used a 20MB file containing a list of email headers, which was 450k lines, and ran the test function shown below, with these results:
 
*1870 matches in 1s for <code>^\(.*www\&.*x\)</code>
 
*1870 matches in 1s for <code>^\(.*www\)\@=\(.*x\)\@=</code>
 
*1870 matches in 5s for <code>.*www\&.*x</code>
 
*1870 matches in 9s for <code>www.*x\|x.*www</code>
 
*1870 matches in 18s for <code>\(www.*x\)\|\(x.*www\)</code>
 
 
Omitting the parens in <code>\(www.*x\)\|\(x.*www\)</code> roughly doubles its speed, by avoiding the overhead of filling in back-references internally.
 
 
While being the shortest pattern, <code>.*www\&.*x</code> is not the fastest. It can be sped up to the same level as <code>^\(.*www\)\@=\(.*x\)\@=</code> (the fastest pattern) with only a slight increase in complexity (anchoring it to the start of the line), though.
 
 
The benchmark function used was:
 
<pre>
 
function TimeSearch(re)
 
let c = 0
 
let t = localtime()
 
exec 'g/'.a:re.'/let c=c+1'
 
return c.' matches in '.(localtime()-t).'s for '.a:re
 
endfunction
 
</pre>
 

Revision as of 00:35, November 1, 2012

select count(*) from apers P, asubject s where p.apnum = s.apnum and p.cschool = s.cschool;

Around Wikia's network

Random Wiki