Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I have to measure execution time for a blocks of code. I had implemented simple StopWatch class like http://www.goldb.org/stopwatchjava.html. If I will invoke methods of StopWatch class directly between business logic then my source code became unreadable and unclean.

What design pattern can be useful in my situation to keep code readable and clean?

share|improve this question
3  
Is your problem to profile code or to build a StopWatch? Because if you are trying to profile your code, it would be better to use tools suitable to such a task and not introduce more code that's unrelated to the business logic being performed. –  Thomas Owens Feb 13 '12 at 16:43
    
In C# I would use a using block to make it clear what block of code I am measuring with the StopWatch class. However, I assume you are not using C# based on the link you provided. –  Bernard Feb 13 '12 at 16:44
    
No, I don't want to use any external tools for code profiling. I want to get measure with helps of my own class. Question is how to separate support code from unrelated business logic at code level? –  coms Feb 13 '12 at 16:49
2  
You may want to look at aspect-oriented programming whose goal is separate cross-cutting concerns (such as logging or maybe profiling) from the main code. –  PersonalNexus Feb 13 '12 at 18:21
add comment

2 Answers

up vote 5 down vote accepted

If you're measuring methods then this is a classic example of cross-cutting concerns that AOP is designed to solve.

My Java is weak, but something like this in C# using PostSharp would work...

Create a ProfileAttribute class that does the profiling and logs it to some log file/database/whatever

public sealed class ProfileAttribute : Attribute
{
    private StopWatch stopWatch;

    public override OnEntry(MethodExecutionArgs args)
    {
        this.stopWatch = new StopWatch();
        this.stopWatch.Start();
    }

    public override OnExit(MethodExecutionArgs args)
    {
        this.stopWatch.Stop();
        /* 
        log(string.Format("[{0}]{1}.{2} took {3}ms", 
            DateTime.Now, 
            args.ClassName, // may not be actual member name, I forget
            args.MethodName, // may not be actual member name, I forget
            stopWatch.Elapsed.TotalMilliseconds));
        */
    }
}

Then, you can attribute any method that you want to profile (without having to clutter up the code too much) just by applying the attribute like so:

[Profile]
public void WatchedMethod()
{
    /* Code */
}

Afterwards, you can check your log(s) and should see something like:

[Jan 1, 2012 00:00:01]MyClass.WatchedMethod took 1.001ms

[Jan 1, 2012 00:00:02]MyClass.WatchedMethod took 1.000ms

[Jan 1, 2012 00:00:03]MyClass.WatchedMethod took 1.002ms

edits

At which point... it makes sense to write a small utility that can pull the data from logs, filter it, and present it in such a way that is usable to you (average the running times, show outlier times, etc.)

Also note that using certain AOP frameworks (maybe AspectJ... not sure) you can also decide what build(s) certain aspects can be built into... ie. you can weave this profile attribute into the debug build, but not weave it into the release build.

Note about runtime performance:

If your weaver is a compile-time weaver, it will inject the aspect's code into your code during the build. Using PostSharp with the example given, the resulting code will be:

private StopWatch stopWatch;

public void WatchedMethod()
{
    this.stopWatch = new StopWatch();
    this.stopWatch.Start();

    /* Code */

    this.stopWatch.Stop();
    /* 
    log(string.Format("[{0}]{1}.{2} took {3}ms", 
        DateTime.Now, 
        args.ClassName, // may not be actual member name, I forget
        args.MethodName, // may not be actual member name, I forget
        stopWatch.Elapsed.TotalMilliseconds));
    */
}
share|improve this answer
    
I wonder if this will give accurate timings. What I mean is how much slower is this than having the start/stop sprinkled in your code? I doubt it will be significant for most apps, but in some mobile games FPS is everything and you don't want as true timings as you can get. –  Joe Feb 13 '12 at 18:53
1  
@joe: Depends on the AOP framework you're using. PostSharp, for example, weaves the code in the aspect directly into the IL of the method during the build so it's precisely as accurate as if you wrote it in the code. Some others are based on reflection and resolve the aspect at runtime... those can be problematic. See my edit. –  Steve Evers Feb 13 '12 at 19:29
add comment

Measuring of execution time is something that isn't a permanent addition to your code, its a temporary thing for the purpose of testing. Its no big deal if your code looks bad while you are testing this, its like adding code for debugging. It should be tossed in where its needed, the results should be recorded and the code removed. Making it look pretty is a waste of time.

If you need to display execution time to your users, then its part of your programs logic and should be directly implemented as part of whatever logic its tracking. It should have minimal effect on the readability of your code as long as you properly designed the stopwatch class itself. There should be any more than about 4 lines added to any area you are measuring, (declare/initialize, start, stop, get time) and it should be of minimal impact unless your existing code is already poorly structured, which is a separate issue.

share|improve this answer
    
Thanks for your answer, but don't want to see even this 4 lines of code. :) Probably something like Decorator pattern can be useful there? –  coms Feb 13 '12 at 17:00
1  
@coms you can't add functionality without adding LOCs –  Ryathal Feb 13 '12 at 17:02
    
I guess, should be way to hide support code from main logic. –  coms Feb 13 '12 at 17:03
    
The code you want to add is either temporary or its business logic based on a requirement. If its not required to continually monitor execution time you are slowing your program down by leaving it there indefinitely and time shouldn't be taken to make temporary code look nice. –  Ryathal Feb 13 '12 at 18:00
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.