Patch 8.0.0504
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)
Files:      src/Makefile, src/create_cmdidxs.pl, src/ex_docmd.c, Filelist


*** ../vim-8.0.0503/src/Makefile        2017-03-21 17:08:46.678923883 +0100
--- src/Makefile        2017-03-25 14:11:14.611853538 +0100
***************
*** 1884,1889 ****
--- 1883,1898 ----
        -rm -rf autom4te.cache
        -rm -f auto/config.status auto/config.cache
  
+ # Run Perl to generate the Ex command lookup table.  This only needs to be run
+ # when a command name has been added or changed.
+ # NOTE: Only works when perl and vim executables are available
+ cmdidxs: ex_cmds.h
+       if test X`perl -e "print 123"` = "X123"; then \
+          vim ex_docmd.c -c 
'/Beginning.*create_cmdidxs/,/End.*create_cmdidxs/! perl create_cmdidxs.pl' -c 
wq; \
+       else \
+          echo Cannot run Perl; \
+       fi
+ 
  # Re-execute this Makefile to include the new auto/config.mk produced by
  # configure Only used when typing "make" with a fresh auto/config.mk.
  myself:
*** ../vim-8.0.0503/src/create_cmdidxs.pl       2017-03-25 14:49:46.422380577 
+0100
--- src/create_cmdidxs.pl       2017-03-25 14:44:17.276864694 +0100
***************
*** 0 ****
--- 1,74 ----
+ #!/usr/bin/perl -w
+ #
+ # This script generates the tables cmdidxs1[] and cmdidxs2[][] which,
+ # given a Ex command, determine the first value to probe to find
+ # a matching command in cmdnames[] based on the first character
+ # and the first 2 characters of the command.
+ # This is used to speed up lookup in cmdnames[].
+ #
+ # Script should be run every time new Ex commands are added in Vim,
+ # from the src/vim directory, since it reads commands from "ex_cmds.h".
+ 
+ # Find the list of Vim commands from cmdnames[] table in ex_cmds.h
+ my @cmds;
+ my @skipped;
+ open(IN, "< ex_cmds.h") or die "can't open ex_cmds.h: $!\n";
+ while (<IN>) {
+   if (/^EX\(CMD_\S*,\s*"([a-z][^"]*)"/) {
+     push (@cmds, $1);
+   } elsif (/^EX\(CMD_/) {
+     push (@skipped, $1);
+   }
+ }
+ 
+ my %cmdidxs1;
+ my %cmdidxs2;
+ 
+ for (my $i = $#cmds; $i >= 0; --$i) {
+   my $cmd = $cmds[$i];
+   my $c1 = substr($cmd, 0, 1); # First character of command.
+ 
+   $cmdidxs1{$c1} = $i;
+ 
+   if (length($cmd) > 1) {
+     my $c2 = substr($cmd, 1, 1); # Second character of command.
+     $cmdidxs2{$c1}{$c2} = $i if (('a' lt $c2) and ($c2 lt 'z'));
+   }
+ }
+ 
+ print "/* Beginning of automatically generated code by create_cmdidxs.pl\n",
+       " *\n",
+       " * Table giving the index of the first command in cmdnames[] to 
lookup\n",
+       " * based on the first letter of a command.\n",
+       " */\n",
+       "static const unsigned short cmdidxs1[26] =\n{\n",
+       join(",\n", map("  /* $_ */ $cmdidxs1{$_}", ('a' .. 'z'))),
+       "\n};\n",
+       "\n",
+       "/*\n",
+       " * Table giving the index of the first command in cmdnames[] to 
lookup\n",
+       " * based on the first 2 letters of a command.\n",
+       " * Values in cmdidxs2[c1][c2] are relative to cmdidxs1[c1] so that 
they\n",
+       " * fit in a byte.\n",
+       " */\n",
+       "static const unsigned char cmdidxs2[26][26] =\n",
+       "{ /*         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";
+ for my $c1 ('a' .. 'z') {
+   print "  /* $c1 */ {";
+   for my $c2 ('a' .. 'z') {
+     if (exists $cmdidxs2{$c1}{$c2}) {
+       printf "%3d,", $cmdidxs2{$c1}{$c2} - $cmdidxs1{$c1};
+     } else {
+       printf "  0,";
+     }
+   }
+   print " }";
+   print "," unless ($c1 eq 'z');
+   print "\n";
+ }
+ print "};\n",
+       "\n",
+       "static int command_count = ", $#cmds + $#skipped + 2 , ";\n",
+       "\n",
+       "/* End of automatically generated code by create_cmdidxs.pl */\n";
+ 
*** ../vim-8.0.0503/src/ex_docmd.c      2017-03-16 17:23:26.819815897 +0100
--- src/ex_docmd.c      2017-03-25 14:44:23.248819614 +0100
***************
*** 495,534 ****
  #define DO_DECLARE_EXCMD
  #include "ex_cmds.h"
  
! /*
!  * Table used to quickly search for a command, based on its first character.
   */
! static cmdidx_T cmdidxs[27] =
  {
!       CMD_append,
!       CMD_buffer,
!       CMD_change,
!       CMD_delete,
!       CMD_edit,
!       CMD_file,
!       CMD_global,
!       CMD_help,
!       CMD_insert,
!       CMD_join,
!       CMD_k,
!       CMD_list,
!       CMD_move,
!       CMD_next,
!       CMD_open,
!       CMD_print,
!       CMD_quit,
!       CMD_read,
!       CMD_substitute,
!       CMD_t,
!       CMD_undo,
!       CMD_vglobal,
!       CMD_write,
!       CMD_xit,
!       CMD_yank,
!       CMD_z,
!       CMD_bang
  };
  
  static char_u dollar_command[2] = {'$', 0};
  
  
--- 495,575 ----
  #define DO_DECLARE_EXCMD
  #include "ex_cmds.h"
  
! /* Beginning of automatically generated code by create_cmdidxs.pl
!  *
!  * Table giving the index of the first command in cmdnames[] to lookup
!  * based on the first letter of a command.
   */
! static const unsigned short cmdidxs1[26] =
  {
!   /* a */ 0,
!   /* b */ 19,
!   /* c */ 42,
!   /* d */ 103,
!   /* e */ 125,
!   /* f */ 145,
!   /* g */ 161,
!   /* h */ 167,
!   /* i */ 176,
!   /* j */ 194,
!   /* k */ 196,
!   /* l */ 201,
!   /* m */ 259,
!   /* n */ 277,
!   /* o */ 297,
!   /* p */ 309,
!   /* q */ 348,
!   /* r */ 351,
!   /* s */ 370,
!   /* t */ 437,
!   /* u */ 472,
!   /* v */ 483,
!   /* w */ 501,
!   /* x */ 516,
!   /* y */ 525,
!   /* z */ 526
  };
  
+ /*
+  * Table giving the index of the first command in cmdnames[] to lookup
+  * based on the first 2 letters of a command.
+  * Values in cmdidxs2[c1][c2] are relative to cmdidxs1[c1] so that they
+  * fit in a byte.
+  */
+ static const unsigned char cmdidxs2[26][26] =
+ { /*         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 */
+   /* a */ {  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  4,  5,  6,  0,  0,  
0,  7, 15,  0, 16,  0,  0,  0,  0,  0, },
+   /* b */ {  0,  0,  0,  4,  5,  7,  0,  0,  0,  0,  0,  8,  9, 10, 11, 12,  
0, 13,  0,  0,  0,  0, 22,  0,  0,  0, },
+   /* c */ {  0, 10, 12, 14, 16, 18, 21,  0,  0,  0,  0, 29, 33, 36, 42, 51, 
53, 54, 55,  0, 57,  0, 60,  0,  0,  0, },
+   /* d */ {  0,  0,  0,  0,  0,  0,  0,  0,  6, 15,  0, 16,  0,  0, 17,  0,  
0, 19, 20,  0,  0,  0,  0,  0,  0,  0, },
+   /* e */ {  0,  0,  2,  0,  0,  0,  0,  0,  0,  0,  0,  7,  9, 10,  0,  0,  
0,  0,  0,  0,  0,  0,  0, 16,  0,  0, },
+   /* f */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  9,  0,  
0,  0,  0,  0, 15,  0,  0,  0,  0,  0, },
+   /* g */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  
0,  2,  0,  0,  4,  5,  0,  0,  0,  0, },
+   /* h */ {  0,  0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  
0,  0,  0,  0,  0,  0,  0,  0,  0,  0, },
+   /* i */ {  0,  0,  0,  0,  0,  3,  0,  0,  0,  4,  0,  5,  6,  0,  0,  0,  
0,  0, 13,  0, 15,  0,  0,  0,  0,  0, },
+   /* j */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  
0,  0,  0,  0,  1,  0,  0,  0,  0,  0, },
+   /* k */ {  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  
0,  0,  0,  0,  0,  0,  0,  0,  0,  0, },
+   /* l */ {  0,  9, 11, 15, 16, 20, 23, 28,  0,  0,  0, 30, 33, 36, 40, 46,  
0, 48, 57, 49, 50, 54, 56,  0,  0,  0, },
+   /* m */ {  0,  0,  0,  0,  7,  0,  0,  0,  0,  0, 10,  0,  0,  0,  0,  0,  
0,  0,  0,  0,  0,  0,  0,  0,  0,  0, },
+   /* n */ {  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  8, 10,  0,  
0,  0,  0,  0, 17,  0,  0,  0,  0,  0, },
+   /* o */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  5,  0,  0,  
0,  0,  0,  0,  9,  0, 11,  0,  0,  0, },
+   /* p */ {  0,  0,  3,  0,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  7,  9,  
0,  0, 16, 17, 26,  0, 27,  0, 28,  0, },
+   /* q */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  
0,  0,  0,  0,  0,  0,  0,  0,  0,  0, },
+   /* r */ {  0,  0,  0,  0,  0,  0,  0,  0, 11,  0,  0,  0,  0,  0,  0,  0,  
0,  0,  0,  0, 13, 18,  0,  0,  0,  0, },
+   /* s */ {  0,  6, 15,  0, 18, 22,  0, 24, 25,  0,  0, 28, 30, 34, 38, 40,  
0, 48,  0, 49,  0, 61, 62,  0, 63,  0, },
+   /* t */ {  0,  0, 19,  0, 22, 23,  0, 24,  0, 25,  0, 26, 27, 28, 29, 30,  
0, 31, 33,  0, 34,  0,  0,  0,  0,  0, },
+   /* u */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 10,  
0,  0,  0,  0,  0,  0,  0,  0,  0,  0, },
+   /* v */ {  0,  0,  0,  0,  1,  0,  0,  0,  4,  0,  0,  0,  9, 12,  0,  0,  
0,  0, 15,  0, 16,  0,  0,  0,  0,  0, },
+   /* w */ {  0,  0,  0,  0,  0,  0,  0,  3,  4,  0,  0,  0,  0,  8,  0,  9, 
10,  0, 12,  0, 13, 14,  0,  0,  0,  0, },
+   /* x */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  5,  0,  0,  
0,  0,  0,  0,  7,  0,  0,  0,  0,  0, },
+   /* y */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  
0,  0,  0,  0,  0,  0,  0,  0,  0,  0, },
+   /* z */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  
0,  0,  0,  0,  0,  0,  0,  0,  0,  0, }
+ };
+ 
+ static int command_count = 539;
+ 
+ /* End of automatically generated code by create_cmdidxs.pl */
+ 
  static char_u dollar_command[2] = {'$', 0};
  
  
***************
*** 614,620 ****
  }
  #endif
  
- 
  /*
   * do_exmode(): Repeatedly get commands for the "Ex" mode, until the ":vi"
   * command is given.
--- 655,660 ----
***************
*** 3208,3217 ****
            }
        }
  
!       if (ASCII_ISLOWER(*eap->cmd))
!           eap->cmdidx = cmdidxs[CharOrdLow(*eap->cmd)];
        else
!           eap->cmdidx = cmdidxs[26];
  
        for ( ; (int)eap->cmdidx < (int)CMD_SIZE;
                               eap->cmdidx = (cmdidx_T)((int)eap->cmdidx + 1))
--- 3248,3271 ----
            }
        }
  
!       if (ASCII_ISLOWER(eap->cmd[0]))
!       {
!           if (command_count != (int)CMD_SIZE)
!           {
!               iemsg((char_u *)_("E943: Command table needs to be updated, run 
'make cmdidxs'"));
!               getout(1);
!           }
! 
!           /* Use a precomputed index for fast look-up in cmdnames[]
!            * taking into account the first 2 letters of eap->cmd. */
!           int c1 = eap->cmd[0];
!           int c2 = eap->cmd[1];
!           eap->cmdidx = cmdidxs1[CharOrdLow(c1)];
!           if (ASCII_ISLOWER(c2))
!               eap->cmdidx += cmdidxs2[CharOrdLow(c1)][CharOrdLow(c2)];
!       }
        else
!           eap->cmdidx = CMD_bang;
  
        for ( ; (int)eap->cmdidx < (int)CMD_SIZE;
                               eap->cmdidx = (cmdidx_T)((int)eap->cmdidx + 1))
*** ../vim-8.0.0503/Filelist    2017-03-12 17:10:14.417925081 +0100
--- Filelist    2017-03-25 14:49:07.770672237 +0100
***************
*** 215,220 ****
--- 215,221 ----
                src/config.mk.in \
                src/configure \
                src/configure.ac \
+               src/create_cmdidxs.pl \
                src/gui_at_fs.c \
                src/gui_at_sb.c \
                src/gui_at_sb.h \
*** ../vim-8.0.0503/src/version.c       2017-03-23 21:53:31.045117492 +0100
--- src/version.c       2017-03-25 13:55:04.375213595 +0100
***************
*** 766,767 ****
--- 766,769 ----
  {   /* Add new patch number below this line */
+ /**/
+     504,
  /**/

-- 
$ echo pizza > /dev/oven

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui