1

I have a bunch of .cpp files which together process similar data files but of various sizes. For the larger data files I want to do some timing studies on the functions inside the .cpp files.

I would like to suppress the output the results for these big data sets, and only print the timing results. For smaller data sets, I would like to print to the screen to verify algorithm/code correctness.

Rather than repeatedly commenting/uncommenting out the appropriate cout statements and recompiling , I would like to use command line arguments (or some other technique) to selectively suppress output.

Any suggestions? The naive one I can think of is use argc and argv, but I am not sure if they are global variables which can be used by functions across different files.

smilingbuddha
  • 14,334
  • 33
  • 112
  • 189
  • 2
    You realise that suppressing output will change how fast your program runs? – flight Sep 20 '11 at 22:20
  • I have separated the comptuation of a result from the printing of the result. Thus timing will not be affected. Thus I can just time the computation which will not change if I suppress the output. – smilingbuddha Sep 20 '11 at 22:42

4 Answers4

4

Of course argv and argc are not global variables, as they are patently function-scope local variables of main():

int main(int argc, char * argv[]) { /* ... */ }

For convenient option processing, you might like to look at getopt.h.


One way to suppress output would be to use grep or file redirection on the shell (time ./prog > /dev/null), but that still incurs the cost of the actual output functions.

I suggest two possible ideas:

  1. Surround your critical functions by calls to clock() and do the measuring and reporting yourself.

  2. Allow the user to pass a verbosity parameter (either at runtime with a command-line option, or at compile time with a #define) and only print depending on the verbosity level.

For idea (1) I use the following macros:

#define CLOCK_TICK(acc, ctr)  ctr = std::clock()
#define CLOCK_TOCK(acc, ctr)  acc += (std::clock() - ctr)
#define CLOCK_RESET(acc) acc = 0
#define CLOCK_REPORT(acc) 1000. * double(acc) / double(CLOCKS_PER_SEC)

For idea (2), I'd do something like this:

#ifndef VERBOSE
#  define VERBOSE 0
#endif

#if VERBOSE > 0
// print level 1
#if VERBOSE > 1
// print level 2
#endif
#endif

Then you can compile with -DVERBOSE=3 etc. to enable logging at a specific level.

If this is too manual, you should look into a proper logging framework for your application.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
4

Your intuition is correct -- use the argc and argv values passed into your main function -- but they are not global variables. You need to make your information global somehow: I'd recommend parsing the arguments once, and keeping a set of global flags that can easily be queried.

For example:

// In a common header file that gets included in each source file
extern bool g_bFlag1;
extern bool g_bFlag2;
...

// In your main source file
bool g_bFlag1 = false;
bool g_bFlag2 = false;
...
int main(int argc, char **argv)
{
    // Parse command line and store results in global flags
    for (int i = 1; i < argc; i++)
    {
        if (strcmp(argv[i], "--flag1") == 0)
            g_bFlag1 = true;
        else if (strcmp(argv[i], "--flag2") == 0)
            g_bFlag2 = true;
        else
            ;  // etc.
    }
}

// In any other source file:
if (g_bFlag1)
{
    // do stuff if and only if g_bFlag1 is set
}

Then you can pass --flag1 on the command line. For more complicated argument parsing, I'd suggest using a library such as GNU getopt.

Adam Rosenfield
  • 390,455
  • 97
  • 512
  • 589
2

By default, all you've got to work with for output are stdout (as cout) and stderr (as cerr).

So some options are:

  • write your timing to stderr, instead of stdout, and pipe them to different places at the command line
  • open a logfile for your timing data, and write to that
  • tag each line of your output with something like "[timing]", then use grep on the command line to only show the output lines you want to see.
adpalumbo
  • 3,031
  • 12
  • 12
0

Usually I use preprocessor directive to do that:

/*inside file_name.cpp*/

//uncomment next line to activate debug print on this file
//#define FILE_NAME_DEBUG  
#ifdef FILE_NAME_DEBUG
cout << "activate debug print\n";
#endif

This approach can selectively suppress the print statement but require to recompile the module each time.

Heisenbug
  • 38,762
  • 28
  • 132
  • 190