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