casual fun with the Perl profiler

call: dproffpp -ap shift.pl

there are three sets of data, each meant to represent a small, medium, or large set. Each set is a list of words, 5, 25, and 100 words long respectively. (realistically the elements would average within 2 to 5 words inclusive). For simplicity N is 10.

There are 2 functions, xx and yy; representing different ways of solving the same problem: pretty printing the last N items of a given data set. In xx(), the set is reversed and then $#set -= N’d to clip all but the last N items, then reversed again to put it back into proper order. In yy() we avoid any reversals and just shift off the front of the list one at a time, until we reach N items left in the set. If the set contains less then N elements, no adjustment need be done.

Each function is called 3 times per iteration, once with each data set, over 3000 iterations (that’s 9000 calls to each function, or 3000 times with each set). The test was then executed 10 times.

The things so simple, it’s not important how long it takes to finish, but I’m interested in how big the the difference is between for (expr1; expr2; expr3) { shift @list } and $#list -= expr; and how much those two reversals hurt.

Every time, yy() ran faster by at least a half second. Then ran tests with xx() doing one reversal, then no reversals and yy() still beat it.

Now out of more curiosity, let’s see how larger data sets work. Each data set now contains 3 words instead of 1, and N is now 43; with the data sets being 5, 25, 100, 250, 500, and 1000 elements long.

A new function, zz() which is xx() without the reversals is also executed during the tests. After running the tests a short duration, it seems that the $#set -= N’ing is a bit faster, more so then the cost of the reversals.

here’s the new run down:

$ do_test() {
> local T=10
> while [ $T -gt 0 ]; do
> N=$1 dprofpp -ap shift.pl | tail -n 7 >> dp
> T=$(($T - 1))
> done
> }
$ for NUM in `builtin echo "3n10n43n51n227n"`; do do_test $NUM; done

The above (z)sh code will execute the test on shift.pl 10 times with an N of 3, 10, 43, 51, and then 227; appending the report (3 subs = (4+3) lines) to the file ‘dp’ for post-cpu meltdown review, otherwise we would have to take a look at all the I/O the tests generate before the report is printed by dprofpp.

Yes, I’m to damn lazy to use command history, let along retype the commands each time; why else would they have invented functions and loops 😛

About 15 minutes and 17 degrees Celsius later, some of the arithmetic involved finally caught up with my throbbing head.

Recap:

  • 5 tests, each test has a different value of N
  • 10 runs of each test, meaning 50 runs
  • each run examines the data sets 3000 times, for 150,000 examinations
  • each examination calls 3 functions once with each of 6 data sets, 18 function calls per examination.
  • The six data sets consists of a list of 5, 25, 100, 250, 500, and 1,000 elements; each element is 3 words long. So like 1880 elements in the data set, and 5,640,000 elements processed per examination

So that is what, maybe 2,700,000 function calls to &xx, &yy, and &zz; without counting the calls within those functions… and 846,000,000,000 list elements processed overall? After a little estimation based on the original data set/run time, I stopped counting after the estimated execution time passed 8 hours * X on this old laptop. Hmm, how’s that old saying go, curiosity fried the geeks cooling fan? lol.

I’m beginning to understand why some peoples workstations have like 32 ~ 64 GB of ECC RAM, and Symmetrical Multiple Processor (SMP) configurations to drool $! for, haha!

Thanks Wiz… lol

After a few other commits, I’ve finally buckled down and made do_getopt() a simple helper, previously it did parsing for @ARGV via the Getopt::Long module, and twiddle %Options accordingly; now it takes an array ref and a hash to do the job. The wonderful thing? Now both tpsh [options] and the built in `set [options]` command work with half a line of duplicated code 🙂

In prepping my code for commit, I wanted to take one last look at do_getopt(), so I went for a quick jump over with the vi/vim :tag command. Wiz IM’d me, so he ended up getting the :ta command instead of vim haha! After alt+tabbing back to the editor, I tried something different just for the heck of it, :ta do_ and guess what!? Vims ex mode completion works on tags as well…. this is so going to spoil me lol. ex/vi lacked command completion, history, and editing; but vim added them. One of these days, I need a refresher on the improved tag commands, my muscle memory is pretty vi compatible until we get into tab completion, :split windows, and multiple tabs lol.

So thanks to Wiz, I’ve just found a lovely Vi IMproved feature that I never dreamed existed xD

Using git for all my scm/vcs needs, I’m starting to wonder how the hell I ever lived with CVS lol. (The documentation for git isn’t to bad these days either)

cvs / git cooperation

http://issaris.blogspot.com/2005/11/cvs-to-git-and-back.html

hmm, might be useful.

Somethings I’d like to work on, are using git, cvs, or svn. My own system here runs CVS, since that’s what OpenBSD comes with, but I’m more used to workign with Subversion. Git and Bazaar-ng are two programs I really should evaluate, since git is likely a program I would love using, and bzr is one I may find more useful in the wider world.

It also pays to know svn/cvs, hehe.

DTrace entry in /usr/src/UPDATING

20080826:
DTrace support was merged to STABLE today. In the best
tradition of “the dog ate my homework”, subversion decided
that the commit message was too large and opted not to send
it. It was a stealth commit!

A ‘make buildkernel’ will now default to build the kernel
and modules with both DTrace kernel hooks and CTF data ready
for DTrace.

After you have installed both world and the kernel, and
rebooted, you can ‘kldload dtraceall’ to load all the DTrace
kernel modules and then you’re set to run the ‘dtrace’
client (as root).

For DTrace documentation, refer to:

We are limited to kernel tracing at the moment, so the pid
provider is not available.

For the syscall provider, note that the arguments to the
return probes are the same as for the entry probes.

hehe, gotta love Subversion 🙂

getting bored

#!/bin/sh
#
# usage: vimbuild [tag]
#
# fetch indicated release tag of vim, compile, and test it.
# Requires the Concurrent Versions System (cvs) or Subversion (svn) client,
# and a suitable make tool.
#
# environment:
#
# $TMPDIR will be used as a staging area if defined, else /tmp is used.
#
# exit status: non zero on failure, zero on success.
#

PATH="/bin:/usr/bin:$PATH"

WORKDIR=${TMPDIR:-/tmp}
VTAG=${1:-vim}
CONFIGURE_ARGS="--enable-perlinterp --enable-pythoninterp --enable-tclinterp --enable-rubyinterp --enable-cscope --enable-fontset --enable-gui=gtk2 --disable-gtktest"

mkdir -p $WORKDIR || exit 1
cd $WORKDIR

# fetch latest vim
if [ -x "`which cvs`" ]; then
echo using cvs
cvs -z3 -d:pserver:anonymous@vim.cvs.sf.net:/cvsroot/vim checkout $VTAG
elif [ -x "`which svn`" ]; then
echo using svn
svn checkout https://vim.svn.sourceforge.net/svnroot/vim/branches/${VTAG}
else
echo 'error, could not find a cvs or svn binary in $PATH!'
exit 1
fi

cd $VTAG
./configure $CONFIGURE_ARGS

#
# set the make command
#
uname | grep -i linux > /dev/null
if [ $? -eq 0 ]; then
NCPU=$(expr `cat /proc/cpuinfo | grep processor | wc -l` * 4)
MAKE="make -j${NCPU}"
else
# assume GNU make is gmake, like on *BSD
if [ ! -x "`which gmake`" ]; then
echo "Warning, GNU make not found!"
echo "This will probably make a GTK gui build fail..."
MAKE=make
else
uname | grep -i bsd > /dev/null
if [ $? ]; then
# check number of cpu via BSD sysctl
NCPU=$(expr `sysctl hw.ncpu | awk '{ print $2 }'` * 4)
MAKE="gmake -j${NCPU}"
else
MAKE=gmake
fi
fi
fi

# now build and test it
$MAKE
if [ -x ./src/vim ]; then
./src/vim --version > /dev/null
if [ $? -eq 0 ]; then
echo "I think the Vi IMproved build was a success"
else
echo "I think the Vi IMproved build was a failure"
echo "Do you wish to test it manually?"
read REP
echo $REP | grep -i y && exec ./src/vim
# NO RETURN on yes
fi
fi

cat << EOF
run: `echo $MAKE | awk '{ print $1 }'` install
as root to finish installing vim
EOF

exit 0

I wonder, if I’ll ever bother to use it lol

Hey, it actually worked lol.

Uploaded it to my server, tweaked the configure args and bingo — freshly updated via

$ vimbuild vim7

$ su – root
# cd /tmp/vim7 && make install

Just for the heck of it, I’ve made the script adapt $CONFIGURE_ARGS based on what it finds installed, hehe.

Source Forge SVN slow !!!

Bah humbug !!!

Tried to checkout a working copy of Neo Ports Manager over SVN, that took twenty minutes or so… Created an independent branch and the starting directory structure for the work I need to get imported, plus copied a few files from the trunk that I also want there.

That took at least 10 minutes to commit..

Looking on Source Forge, I can see that two other people have filed about the SVN services being so dang gum slow.

Looks like it might be awhile before I finally get my latest stuff under revision control +S.

Note to self, don’t use GNU m4 on Win32

Bah, humbug !!!

the focal point of the entire operation is a suitable pre-processor.

The idea:

defined test substitution macros generated by front end for pre processor

template file that relies upon said macros

output to be generated from preprocessing the macros from in the template.

The problem?

Target platform: MicroShaft Windows NT 5.1 (XP)

At first I figured I would use the C Pre-Processor since MinGW is on the target box, along with several other development tools.

Then I remembered I have GNU utilities for Win32 installed on this machine. So I took a look and found that a port of GNU m4 v1.4 is installed. I learned enough of the m4 ‘macro’ language just for tasks like this but guess what!

m4.exe fails to expand all macros in the template file.

Being more then somewhat disappointed, I ssh’d into my OpenBSD machine and fed it through the m4 implementation it comes with (not GNU), and guess what?

That freaking works fine.

*unzips fly, pisses on m4.exe*

Odds are the 1.4.11 version of GNU m4 I have on FreeBSD installed from ports works, hell scripting OpenBSDs sed works for this task, let along custom perl !

So I’ve just used vim to quickly :%s/m4 defines/cpp defines and seem to have to use that in order to get it working. Nice, simple, and effective.

*grrrrr*

Speed Learning — m4

Was on my way to bed (read sitting in front of my laptop <_<) and caught The One on TV just 10 minutes into it. I had seen part of it before but never got to see the second half 🙁

Now in search of something else to watch, I noticed that Live Free or Die Hard starts in at 0140Q, it’s currently 0112Q — so…

Early today I found out that the m4 macro language processor is not a ‘GNU Thing’ although GNU m4 is used as part of the gnu tool chain. Since it’s a language dating back to the 1970s and I could rather use something like m4 from the looks of it.

Let’s see how much I can learn from FreeBSDs m4 manual page before the movie starts hehe 🙂

Tick tock