写入属性列表是否比写入令牌列表花费更长的时间?

写入属性列表是否比写入令牌列表花费更长的时间?

在问题中使用 pgfplotstable 有选择地将一列写入适当的行?我提出以下建议:

\documentclass{article}

\usepackage{xparse}
\usepackage{booktabs}
\usepackage{longtable}
\usepackage{filecontents}

\begin{filecontents*}{namespgfa.csv}
5501,Kathirvelu A
5502,Gugan K
5503,Kalaitchelvi S
5504,Suresh S
5505,Mahesh K
\end{filecontents*}
%
\begin{filecontents*}{markspgfa.csv}
5501,67
5502,25
5503,62
5505,95
\end{filecontents*}

\ExplSyntaxOn
\tl_new:N \g_tab_rows_tl
\ior_new:N \g_names_ior
\ior_new:N \g_marks_ior
\prop_new:N \g_names_prop

\ior_open:Nn \g_names_ior {namespgfa.csv}
\ior_open:Nn \g_marks_ior {markspgfa.csv}

\cs_new:Npn \set_name_keys:w #1,#2\q_stop
    {
        \prop_put:Nnn \g_names_prop {#1} {#2}
    }

\cs_new:Npn \tab_write_keys:w #1,#2\q_stop 
    {
        \prop_gpop:NnN \g_names_prop {#1} \l_tmpa_tl 
        \tl_gput_right:Nn \g_tab_rows_tl {#1&} 
        \tl_gput_right:NV \g_tab_rows_tl \l_tmpa_tl
        \tl_gput_right:Nn \g_tab_rows_tl {&#2\\} 
    }
%replacing the above two control sequences with the following slows compilation substantially
%\cs_new:Npn \set_name_keys:w #1,#2\q_stop
%   {
%        \prop_put:Nnn \g_names_prop {#1} {#1&#2&}
%   }
%
%\cs_new:Npn \tab_write_keys:w #1,#2\q_stop
%    {
%        \prop_gpop:NnN \g_names_prop {#1} \l_tmpa_tl
%        \tl_gput_right:NV \g_tab_rows_tl \l_tmpa_tl
%        \tl_gput_right:Nn \g_tab_rows_tl {#2\\}
%    }

\ior_str_map_inline:Nn \g_names_ior
    {
        \set_name_keys:w #1\q_stop
    }

\ior_str_map_inline:Nn \g_marks_ior
    {
        \tab_write_keys:w #1\q_stop
    }

\ior_close:N \g_names_ior
\ior_close:N \g_marks_ior

\NewDocumentCommand { \WriteRows } {}
    {
        \tl_use:N \g_tab_rows_tl
    }

\ExplSyntaxOff

\begin{document}

\begin{longtable}{clc}
Reg.No.&Name&Marks\\
\toprule
\WriteRows
\bottomrule
\end{longtable}

\end{document}

背景:namespgfa.csv和 的第一列markspgfa.csv包含 ID 号,而第二列分别包含相应的名称和标记。这个想法非常简单:将每个 ID 与一个名称关联,并将该名称插入表中相应的 ID 和标记之间。由于速度是一个问题,我认为上述代码中注释的更改可能会加快速度。我的想法是,对于带有.csvn的 ,无论如何\set_name_keys:w都会被调用n次,因此使用该 cs 写入一些额外信息将节省~n对 的调用\tl_gput_right:Nn \g_tab_rows_tl {#1&}。然而,在 4000 行的测试中.csv's,第二种方法花费约 30 秒,而第一种方法花费约 25 秒。

我的问题是:为什么编译时间会有如此大的差异?

以下是我使用的测试文件:

  1. 标记http://www.smallfiles.org/download/1451/markspgf.csv.html
  2. 名称spgfhttp://www.smallfiles.org/download/1452/namespgf.csv.html

\ior_open:Nn \g_names_ior {namespgfa.csv}要使用这些,请从和中的文件名中删除“a” \ior_open:Nn \g_marks_ior {markspgfa.csv}

答案1

最终,expl3prop数据类型是使用 TeX 宏构造的(目前:我们曾经使用标记寄存器)。当您分配给 时prop,赋值首先需要“查找”键,然后才能添加新的键/值对或替换现有键的值。这是使用 TeX 级别的分隔宏完成的。因此,当您添加到 时prop,TeX 必须读取底层宏中的所有标记,随着内容变大,速度会变慢。另一方面,分配给tl(它也是 TeX 级别的宏)不涉及解析步骤,因此唯一需要考虑的大小是您要添加的内容,而不是已经存在的内容。因此,最终任何使prop变量变大的操作都会减慢速度。这当然是一种平衡(因为每次赋值都需要时间),但如果您正在查看非常大的结构和大量的标记,那么拆分事物可能会更有效率。

(团队 SVN 中有一个实验性的“数据表”数据类型。这显示了同样的问题,但程度更大,我打算修改代码以使用更多的 csname,每个 csname 包含更少的数据,因为这里的平衡显然是错误的。)

相关内容