views:

971

answers:

6

I have a couple variants of a program that I want to compare on performance. Both perform essentially the same task.

One does it all in C and memory. The other calls an external utility and does file IO.

How do I reliably compare them?

1) Getting "time on CPU" using "time" favors the second variant for calling system() and doing IO. Even if I add "system" time to "user" time, it'll still not count for time spent blocked on wait().

2) I can't just clock them for they run on a server and can be pushed off the CPU any time. Averaging across 1000s of experiments is a soft option, since I have no idea how my server is utilized - it's a VM on a cluster, it's kind of complicated.

3) profilers do not help since they'll give me time spent in the code, which again favors the version that does system()

I need to add up all CPU time that these programs consume, including user, kernel, IO, and children's recursively.

I expected this to be a common problem, but still don't seem to find a solution.

(Solved with times() - see below. Thanks everybody)

+1  A: 

If I've understood, typing "time myapplication" on a bash command line is not what you are looking for.

If you want accuracy, you must use a profiler... You have the source, yes?

Try something like Oprofile or Valgrind, or take a look at this for a more extended list.

If you haven't the source, honestly I don't know...

Myrrdyn
+1  A: 

Run them a thousand times, measure actual time taken, then average the results. That should smooth out any variances due to other applications running on your server.

davr
A: 

fprof is your friend

dsm
frpof, I guess, only profiles my code. It'll give me clock-on-the-wall time for the system(), which is same as using "time" on the whole thing
n-alexander
A: 

I'd probably lean towards adding "time -o somefile" to the front of the system command, and then adding it to the time given by time'ing your main program to get a total. Unless I had to do this lots of times, then I'd find a way to take two time outputs and add them up to the screen (using awk or shell or perl or something).

Tanktalus
that'd work a single step down the fork chain. If my external command runs any more children - which I don't know - I'll get wrong results
n-alexander
+1  A: 

/usr/bin/time (not built-in "time" in bash) can give some interesting stats.

$ /usr/bin/time -v xeyes
    Command being timed: "xeyes"
    User time (seconds): 0.00
    System time (seconds): 0.01
    Percent of CPU this job got: 0%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:04.57
    Average shared text size (kbytes): 0
    Average unshared data size (kbytes): 0
    Average stack size (kbytes): 0
    Average total size (kbytes): 0
    Maximum resident set size (kbytes): 0
    Average resident set size (kbytes): 0
    Major (requiring I/O) page faults: 9
    Minor (reclaiming a frame) page faults: 517
    Voluntary context switches: 243
    Involuntary context switches: 0
    Swaps: 0
    File system inputs: 1072
    File system outputs: 0
    Socket messages sent: 0
    Socket messages received: 0
    Signals delivered: 0
    Page size (bytes): 4096
    Exit status: 0
Dustin
doesn't give me children's times, but useful anyway
n-alexander
+1  A: 

I seem to have found it at last.

NAME times - get process times

SYNOPSIS #include

   clock_t times(struct tms *buf);

DESCRIPTION times() stores the current process times in the struct tms that buf points to. The struct tms is as defined in :

   struct tms {
          clock_t tms_utime;  /* user time */
          clock_t tms_stime;  /* system time */
          clock_t tms_cutime; /* user time of children */
          clock_t tms_cstime; /* system time of children */
   };

The children's times are a recursive sum of all waited-for children.

I wonder why it hasn't been made a standard CLI utility yet. Or may be I'm just ignorant.

n-alexander