Skip to content

Instantly share code, notes, and snippets.

@zr-tex8r
Created August 12, 2018 19:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zr-tex8r/3a3b6179e01425f351f3639818bf3284 to your computer and use it in GitHub Desktop.
Save zr-tex8r/3a3b6179e01425f351f3639818bf3284 to your computer and use it in GitHub Desktop.
TeX: Experiments on time complexity models
use v5.12;
use Time::HiRes 'time';
use List::Util qw( sum max min );
my $program = "timemodel";
my $verbose = 0;
sub main {
printf("%-18s avg--- sd---- max--- min---\n", "");
foreach my $n (0, 1, 10, 100, 1000) {
my $lbl = ($n <= 0) ? "Base" : "Len-$n";
my $src = tex_source($n, 1000000);
my @res = measure_elapse("latex", $src);
printf("[%-16s] %6.3f %6.3f %6.3f %6.3f\n", $lbl, @res);
}
}
use constant {
MEC => 100,
MEWC => 5,
};
my $metemp = sprintf("__mex%05d", $$);
sub measure_elapse {
#select((select(STDERR), $|=1)[0]);
my ($cmd, $src) = @_;
my $bsrc = "$metemp" . "xx";
my $cmdf = "$cmd --halt-on-error -interaction=nonstopmode " .
"$bsrc.tex 2>$bsrc.stderr 1>$bsrc.stdout";
# make file
info("source file", "$bsrc.tex");
open(my $ho, '>', "$bsrc.tex") or die "Cannot write '$bsrc'";
print $ho ($src);
close($ho);
# warm up
for (1 .. MEWC) {
unlink("$bsrc.aux");
(system($cmdf) == 0) or die "Command failed";
info("warm up #$_");
}
my @out = grep { $_ ne "$bsrc.tex" } (glob("$bsrc*.*"));
# measure
my @elapse;
for (1 .. MEC) {
print STDERR "<$_>\r";
unlink(@out);
my $tick1 = time();
system($cmdf);
my $tick2 = time();
push(@elapse, $tick2 - $tick1);
info("measure #$_", sprintf("%.3f", $tick2 - $tick1));
}
unlink(glob("$bsrc*.*"));
my $avg0 = sum(@elapse) / scalar(@elapse);
@elapse = grep { $_ <= $avg0 * 1.5 } (@elapse); # purge outliers
my $avg = sum(@elapse) / scalar(@elapse);
my $sd = sqrt(sum(map { ($_ - $avg) ** 2 } (@elapse)) / (scalar(@elapse) - 1));
return $avg, $sd, max(@elapse), min(@elapse);
}
sub tex_source {
my ($n, $lc) = @_; my (@cnk);
my $AAA = 'A' x $n;
local $_ = <<'EOT';
\documentclass{article}
\def\S#1\E{}
\def\A{\S <AAA>\E}
\begin{document}
EOT
s/<AAA>/$AAA/; push(@cnk, $_);
my $l = ($n <= 0) ? "\\par\n" : "\\A\\par\n";
for (1 .. $lc) { push(@cnk, $l); }
push(@cnk, <<'EOT');
\end{document}
EOT
return join("", @cnk);
}
sub info {
print STDERR (join(": ", $program, @_), "\n") if ($verbose);
}
main();
=nop
avg--- sd---- max--- min---
[Base ] 2.285 0.016 2.327 2.247
[Len-1 ] 2.490 0.027 2.639 2.438
[Len-10 ] 2.640 0.019 2.717 2.592
[Len-100 ] 4.111 0.025 4.251 4.077
[Len-1000 ] 18.837 0.072 19.322 18.749
=cut
use v5.12;
use Time::HiRes 'time';
use List::Util qw( sum max min );
my $program = "timemodel";
my $verbose = 0;
sub main {
printf("%-18s avg--- sd---- max--- min---\n", "");
# foreach my $n (1, 10, 100, 1000, 10000, 18000, 32000, 56000, 100000, 180000, 320000) {
foreach my $n (0, 1, 1000, 10000, 100000, 470000) {
my $lbl = ($n <= 0) ? "Base" : "Set-$n";
my $src = tex_source($n, 1000000);
my @res = measure_elapse("latex", $src);
printf("[%-16s] %6.3f %6.3f %6.3f %6.3f\n", $lbl, @res);
}
}
use constant {
MEC => 100,
MEWC => 5,
};
my $metemp = sprintf("__mex%05d", $$);
sub measure_elapse {
#select((select(STDERR), $|=1)[0]);
my ($cmd, $src) = @_;
my $bsrc = "$metemp" . "xx";
my $cmdf = "$cmd --halt-on-error -interaction=nonstopmode " .
"$bsrc.tex 2>$bsrc.stderr 1>$bsrc.stdout";
# make file
info("source file", "$bsrc.tex");
open(my $ho, '>', "$bsrc.tex") or die "Cannot write '$bsrc'";
print $ho ($src);
close($ho);
# warm up
for (1 .. MEWC) {
unlink("$bsrc.aux");
(system($cmdf) == 0) or die "Command failed";
info("warm up #$_");
}
my @out = grep { $_ ne "$bsrc.tex" } (glob("$bsrc*.*"));
# measure
my @elapse;
for (1 .. MEC) {
print STDERR "<$_>\r";
unlink(@out);
my $tick1 = time();
system($cmdf);
my $tick2 = time();
push(@elapse, $tick2 - $tick1);
info("measure #$_", sprintf("%.3f", $tick2 - $tick1));
}
unlink(glob("$bsrc*.*"));
my $avg0 = sum(@elapse) / scalar(@elapse);
@elapse = grep { $_ <= $avg0 * 1.5 } (@elapse); # purge outliers
my $avg = sum(@elapse) / scalar(@elapse);
my $sd = sqrt(sum(map { ($_ - $avg) ** 2 } (@elapse)) / (scalar(@elapse) - 1));
return $avg, $sd, max(@elapse), min(@elapse);
}
use constant {
RSEED => 2222181,
MAXWD => 500000,
};
srand(RSEED);
my @alpha = ('A'..'Z'); my @nonce;
for (1 .. MAXWD) {
push(@nonce, join('', map { $alpha[int(rand() * 26)] } (0..9)));
}
sub tex_source {
my ($n, $lc) = @_; my (@cnk);
($n <= scalar(@nonce)) or die;
push(@cnk, <<'EOT');
\documentclass{article}
\begin{document}
EOT
if ($n <= 0) {
foreach my $k (0 .. $lc-1) {
push(@cnk, "\\relax\n");
}
} else {
foreach my $k (0 .. $lc-1) {
my $w = $nonce[$k % $n];
push(@cnk, "\\let\\xyz$w\\relax\n");
}
}
push(@cnk, <<'EOT');
\end{document}
EOT
return join("", @cnk);
}
sub info {
print STDERR (join(": ", $program, @_), "\n") if ($verbose);
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment