Profiling Your Tcl – Output to CSV

This is the last part of the Tcl profiler series. In part one, I presented a 5-line tool which profiles your Tcl script. In part two, I refined it to show sorted timings and number of calls. In this part, I am going to create a tool to output the profiler information to a CSV file, useful for using it with other analysis tools such as Excel.

The Tool

Save the following script to a file and call it profile_me_v3.

#!/usr/bin/env tclsh

# File: profile_me_v3

namespace eval profiler_utils {
    proc getHeaders {info} {
        set headers {function}
        foreach {k v} $info {
            lappend headers $k
        return [join $headers ,]
    proc getValues {function info} {
        set values $function
        foreach {k v} $info {
            lappend values $v
        return [join $values ,]

    proc reportStatistics {} {
        set outfile [open "profile_me_v3.csv" w]
        set needHeaders 0
        foreach {function info} [::profiler::dump] {
            if {$needHeaders == 0} {
                puts $outfile [getHeaders $info]
            incr needHeaders
            puts $outfile [getValues $function $info]
        close $outfile

package require profiler

# Call the script
set scriptName [lindex $::argv 0]
set ::argv [lrange $::argv 1 end]
source $scriptName

# Lastly, display profiler info


After profiling a script, function reportStatistics (line 22-33) opens a CSV file and and writes to it the headers (line 27) and one line for each function (line 30). The variable needHeaders is used to ensure the headers are written only once.

Note that the function ::profiler::dump returns a list of alternate values: the function name and a sublist (info). The sublist, in turn, contains name/value pairs of profiler info.

Note also that function reportStatistics hard-codes its output to a file named “profile_me_v3.csv” for the sake of simplicity. As an exercise, you might want to change the file name based on the scriptName variable.

Below is the contents of the CSV file:

::call_all_tests,1,GLOBAL 1,133870,133870,0,0,0,45792,45792,::test1 ::test2
::test1,6,GLOBAL 5 ::call_all_tests 1,121579,233013,38835,40568,104.5,0,0,
::test2,11,GLOBAL 10 ::call_all_tests 1,24335,228723,20793,1412,6.8,0,0,

When viewed in a spreadsheet application, the above CSV might look like this:

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s