Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Faster \cs_if_free:N tests, for faster loading #17

Closed
blefloch opened this issue Apr 20, 2011 · 6 comments
Closed

Faster \cs_if_free:N tests, for faster loading #17

blefloch opened this issue Apr 20, 2011 · 6 comments
Labels
enhancement New feature or request

Comments

@blefloch
Copy link
Member

Loading speed is an issue for slow computers. One very much used function is \cs_new:Npn. Currently \cs_new:Npn \foo:N produces 138 lines in the log. With the changes below, we reduce to 75 lines. It seems to speed up the loading by roughly 10% (I was hoping for more...). On a similar note, I would advise against using the Nn variants, which take ~100 more lines...

Proposal to change \cs_if_free:N to

\prg_set_conditional:Npnn \cs_if_free:N #1 {p,TF,T,F} {
  \cs_if_exist:NTF #1 
  \prg_return_false:
  { \cs_if_do_not_use_r:N #1 }
}

where the _r variant of \cs_if_do_not_use:N is defined below.

Currently \cs_if_do_not_use_p:N #1 returns true if

  • #1 has : in its \cs_to_str:N, and
  • the part after : is exactly D.

This is equivalent to

  • #1 finishes with :D, and
  • there is no other : in its name.

I propose to relax the second condition (refusing slightly more functions) to get a faster test, which just checks whether the name finishes with :D.

\group_begin:
  \tex_catcode:D `\; = 12\tex_relax:D 
  \tex_uccode:D `\; = `\:
  \tex_catcode:D `\O = 12\tex_relax:D
  \tex_uccode:D `\O = `\D
  \tex_uccode:D `\- = `\-
  \tex_uccode:D `\` = `\`
  \tex_uccode:D `\= = `\=
  \tex_uccode:D `\: = `\:
\tex_uppercase:D 
{
  \group_end:

A slightly weird kind of conditional, which does \prg_return_true/false: rather than expanding to \c_true/false_bool as the predicate variant, or to some \use for the TF variants.

  % used for "\cs_if_free"
  \cs_set:Npn \cs_if_do_not_use_r:N #1 {
    \tex_ifcat:D X 
                 \exp_after:wN \cs_if_do_not_use_aux: 
                 \token_to_str:N #1 A ;O A
                 X
      \prg_return_true:
    \else:
      \prg_return_false:
    \fi:
  }

The predicate variant seems to be used somewhere in l3expan.

  \cs_set:Npn \cs_if_do_not_use_p:N #1 {
    \tex_ifcat:D X 
                 \exp_after:wN \cs_if_do_not_use_aux: 
                 \token_to_str:N #1 A ;O A
                 X
      \exp_after:wN \c_false_bool
    \else:
      \exp_after:wN \c_true_bool
    \fi:
  }

We need something special just for the case of the cs \D when the escape character is : (just one tiny case :-s). Otherwise, we grab until :DA, where A has catcode letter (hence not present in the result of \token_to_str:N).

  \cs_set:Npn \cs_if_do_not_use_aux: {
    \tex_ifnum:D `\: = \tex_escapechar:D
      \exp_after:wN \use_i:nn
    \fi:
    \blf_cs_if_do_not_use_aux:w
  }
  \cs_set:Npn \cs_if_do_not_use_aux:w #1 ;O A { }
}

Don't trust this code: I might have screwed up slightly.

@josephwright
Copy link
Member

On the Nn variant, this is well-known: I'd like to drop them, but I know Will is of the opposite opinion

@wspr
Copy link
Contributor

wspr commented Apr 21, 2011

Right, we've already agreed that kernel code is to be written with the Npn variants only for this reason. I'd go so far as to suggest defining an "optimised" \cs_new:Npn for the kernel, skipping the slower checks, and then replacing it at the end of the loading. I.e.,

  1. define simpler \cs_new:Npn
  2. load the rest of expl3
  3. redefine \cs_new:Npn to the slower definition

I'd actually go further and say we should drop the extra check for :D endings unless the l3chk module (one way or another) is loaded.

@josephwright
Copy link
Member

I'm no so sure about having different definitions for \cs_new:Npn within the kernel and outside (this sounds like 'asking fro trouble'). However, I'd agree on the :D business: it does seem like overkill (after all, we don't have any other enforcement of conventions, and I'm not sure we really can.)

@wspr
Copy link
Contributor

wspr commented Apr 21, 2011

Okay, let's pencil in to move the :D checking to an optional part of the chk module. (Bruno, in case it's not clear, the "check" module is designed to be loaded optionally to enforce some of the expl3 coding conventions. We haven't been supporting it, but the idea is to get it up and running again at some stage.)

@josephwright
Copy link
Member

Sounds OK to me.

@josephwright
Copy link
Member

Done in the 'big bang' code: to commit later today

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants