Mercurial > vim
comparison src/create_cmdidxs.pl @ 11236:62c96fee518e v8.0.0504
patch 8.0.0504: looking up an Ex command is a bit slow
commit https://github.com/vim/vim/commit/e5e0fbcd4244d032a0635ad7defe2831f251c639
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Mar 25 14:51:01 2017 +0100
patch 8.0.0504: looking up an Ex command is a bit slow
Problem: Looking up an Ex command is a bit slow.
Solution: Instead of just using the first letter, also use the second letter
to skip ahead in the list of commands. Generate the table with a
Perl script. (Dominique Pelle, closes #1589)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sat, 25 Mar 2017 15:00:05 +0100 |
parents | |
children | 17ba19406c50 |
comparison
equal
deleted
inserted
replaced
11235:9b7de4c4fd04 | 11236:62c96fee518e |
---|---|
1 #!/usr/bin/perl -w | |
2 # | |
3 # This script generates the tables cmdidxs1[] and cmdidxs2[][] which, | |
4 # given a Ex command, determine the first value to probe to find | |
5 # a matching command in cmdnames[] based on the first character | |
6 # and the first 2 characters of the command. | |
7 # This is used to speed up lookup in cmdnames[]. | |
8 # | |
9 # Script should be run every time new Ex commands are added in Vim, | |
10 # from the src/vim directory, since it reads commands from "ex_cmds.h". | |
11 | |
12 # Find the list of Vim commands from cmdnames[] table in ex_cmds.h | |
13 my @cmds; | |
14 my @skipped; | |
15 open(IN, "< ex_cmds.h") or die "can't open ex_cmds.h: $!\n"; | |
16 while (<IN>) { | |
17 if (/^EX\(CMD_\S*,\s*"([a-z][^"]*)"/) { | |
18 push (@cmds, $1); | |
19 } elsif (/^EX\(CMD_/) { | |
20 push (@skipped, $1); | |
21 } | |
22 } | |
23 | |
24 my %cmdidxs1; | |
25 my %cmdidxs2; | |
26 | |
27 for (my $i = $#cmds; $i >= 0; --$i) { | |
28 my $cmd = $cmds[$i]; | |
29 my $c1 = substr($cmd, 0, 1); # First character of command. | |
30 | |
31 $cmdidxs1{$c1} = $i; | |
32 | |
33 if (length($cmd) > 1) { | |
34 my $c2 = substr($cmd, 1, 1); # Second character of command. | |
35 $cmdidxs2{$c1}{$c2} = $i if (('a' lt $c2) and ($c2 lt 'z')); | |
36 } | |
37 } | |
38 | |
39 print "/* Beginning of automatically generated code by create_cmdidxs.pl\n", | |
40 " *\n", | |
41 " * Table giving the index of the first command in cmdnames[] to lookup\n", | |
42 " * based on the first letter of a command.\n", | |
43 " */\n", | |
44 "static const unsigned short cmdidxs1[26] =\n{\n", | |
45 join(",\n", map(" /* $_ */ $cmdidxs1{$_}", ('a' .. 'z'))), | |
46 "\n};\n", | |
47 "\n", | |
48 "/*\n", | |
49 " * Table giving the index of the first command in cmdnames[] to lookup\n", | |
50 " * based on the first 2 letters of a command.\n", | |
51 " * Values in cmdidxs2[c1][c2] are relative to cmdidxs1[c1] so that they\n", | |
52 " * fit in a byte.\n", | |
53 " */\n", | |
54 "static const unsigned char cmdidxs2[26][26] =\n", | |
55 "{ /* a b c d e f g h i j k l m n o p q r s t u v w x y z */\n"; | |
56 for my $c1 ('a' .. 'z') { | |
57 print " /* $c1 */ {"; | |
58 for my $c2 ('a' .. 'z') { | |
59 if (exists $cmdidxs2{$c1}{$c2}) { | |
60 printf "%3d,", $cmdidxs2{$c1}{$c2} - $cmdidxs1{$c1}; | |
61 } else { | |
62 printf " 0,"; | |
63 } | |
64 } | |
65 print " }"; | |
66 print "," unless ($c1 eq 'z'); | |
67 print "\n"; | |
68 } | |
69 print "};\n", | |
70 "\n", | |
71 "static int command_count = ", $#cmds + $#skipped + 2 , ";\n", | |
72 "\n", | |
73 "/* End of automatically generated code by create_cmdidxs.pl */\n"; | |
74 |