在问题中使用 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 {\\}
}
%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&}
% }
%
%\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 和标记之间。由于速度是一个问题,我认为上述代码中注释的更改可能会加快速度。我的想法是,对于带有.csv
行n
的 ,无论如何\set_name_keys:w
都会被调用n
次,因此使用该 cs 写入一些额外信息将节省~n
对 的调用\tl_gput_right:Nn \g_tab_rows_tl {#1&}
。然而,在 4000 行的测试中.csv's
,第二种方法花费约 30 秒,而第一种方法花费约 25 秒。
我的问题是:为什么编译时间会有如此大的差异?
以下是我使用的测试文件:
- 标记http://www.smallfiles.org/download/1451/markspgf.csv.html
- 名称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
最终,expl3
的prop
数据类型是使用 TeX 宏构造的(目前:我们曾经使用标记寄存器)。当您分配给 时prop
,赋值首先需要“查找”键,然后才能添加新的键/值对或替换现有键的值。这是使用 TeX 级别的分隔宏完成的。因此,当您添加到 时prop
,TeX 必须读取底层宏中的所有标记,随着内容变大,速度会变慢。另一方面,分配给tl
(它也是 TeX 级别的宏)不涉及解析步骤,因此唯一需要考虑的大小是您要添加的内容,而不是已经存在的内容。因此,最终任何使prop
变量变大的操作都会减慢速度。这当然是一种平衡(因为每次赋值都需要时间),但如果您正在查看非常大的结构和大量的标记,那么拆分事物可能会更有效率。
(团队 SVN 中有一个实验性的“数据表”数据类型。这显示了同样的问题,但程度更大,我打算修改代码以使用更多的 csname,每个 csname 包含更少的数据,因为这里的平衡显然是错误的。)