---
title: "Performance vs. Testability and semi-virtual method calls"
url: "https://osherove.com/blog/2005/7/10/performance-vs-testability-and-semi-virtual-method-calls.md"
canonical: "https://osherove.com/blog/2005/7/10/performance-vs-testability-and-semi-virtual-method-calls.html"
published: "2005-07-10T22:58:00"
updated: "2005-07-10T22:58:00"
tags: ["Agile Related", "Testing Guidelines"]
author: "Roy Osherove"
description: "I won't try to sit here and say that the issue of performance vs. testability can be summed up in one blog post (or a full article for that matter). However, it's an important one and during my consulting gigs I've come…"
usage: "Licensed under CC BY 4.0 — reuse, quote and adapt with attribution (Roy Osherove, link to the original page)."
license: "https://creativecommons.org/licenses/by/4.0/"
---

# Performance vs. Testability and semi-virtual method calls

By Roy Osherove July 10, 2005 In [Agile Related](https://osherove.com/blog/category/agile-related), [Testing Guidelines](https://osherove.com/blog/category/testing-guidelines)

**Historical article** · Originally published July 10, 2005; technical details may be outdated.

I won't try to sit here and say that the issue of performance vs. testability can be summed up in one blog post (or a full article for that matter). However, it's an important one and during my consulting gigs I've come across some interesting questions and answers regarding this area. Here are some of my thoughts on this.

In languages like C++ developing real-time performing applications may also mean having coding-call standards such as "do not use virtual functions" in the feat that a virtual call repeated enough times may slow the system substantially. Unfortunately, avoiding virtual calls takes away a lot of the testability aspect of code, especially when dealing with legacy code, or real time code. The problem is that for your tests to be able to instantiate specific classes or simulate specific situations, a virtual call may save the day by allowing you to perform what's commonly known as "Inherit & Override" whereby you'd create a class that \*inherits\* from your class under test and then overrides specific methods which may control various inputs into the class or solve timing and other dependency issues. Taking a simple MailSender class as an example, you might want to override a MailSender's "SendDataToExchangeServer" virtual method and implement it as an empty method instead of making all the way through to a real exchange server.

This in turn allows your tests to use the \*inherited\* class and avoid any unneeded or timely calls to real servers. They can then simulate various problems with the server such as throwing an exception in the overridden call and see what happens in the class under test. The concept is not a very complicated one but you may need a few readings in order to get it (I suggest you try it with one of your own classes you'd like to test).

In any case, this simple method of removing a dependency is impossible to implement without a virtual method (not an an easy enough manner, anyway). What should you do when faced with the problem of conflicting constraints-- you'd like to test the class but testing it might make it less performing:

- "[Premature optimization is the root of all evil](http://www.cookcomputing.com/blog/archives/000084.html)": Consider making the method virtual anyway. In fact, one of the first things you learn in a software optimization course is this: "Make it work, **then** optimize it". Same thing here. Make the software work, and make sure you know it works with tests. When it does work, if you still need to optimize it, you'll have what I call as "**known optimization points**"  - profile your code and see what part of code is the most problematic perf wise. If it's due to a virtual method that could have been non virtual, you can remove that "virtual" part and you've just optimized your application. Of course, that part is now no longer testable.
- Optimize early - lose testability, That's the worst way to go.
- Combine the two approaches: use what I fondly call "Semi-Virtual method calls". What are those? well, they're methods which, when compiled with tests, act as virtual functions, and when compiled without tests act as non virtual functions. The easiest way to do this is to simply write the "virtual" part on a different line and surround it with "#ifdef"s or macros like so:

**public**

**#ifdef(UNIT\_TEST) virtual #endif**

**void domeSomethingFast(int num){...}**

You can apply this approach in many different syntaxes, but the main thing is that the tests get what they need and your code gets what it needs. Notice however, that you're taking the "premature optimization" approach here for your Production code anyway. You're testing its logic, yes. but you're still optimizing really early.

## Lessons on this topic

- [Extract And Override Focus](https://courses.osherove.com/courses/legacy-code-hero/extract-and-override-focus/) · Legacy Code Hero

## More in Agile Related

[All posts in Agile Related](https://osherove.com/blog/category/agile-related)

- Jul 25, 2005

    ### [XP Games links](https://osherove.com/blog/2005/7/25/xp-games-links.html)

- Jul 25, 2005

    ### [\[Article\] The Test Feasibility Matrix](https://osherove.com/blog/2005/7/25/article-the-test-feasibility-matrix.html)

- Jul 1, 2005

    ### [Rhino.Mocks v. 2.0 Announced. Yes, it's a Mock Object Framework.](https://osherove.com/blog/2005/7/1/rhinomocks-v-20-announced-yes-its-a-mock-object-framework.html)

- Jun 30, 2005

    ### [The Mock Objects elevator speech](https://osherove.com/blog/2005/6/30/the-mock-objects-elevator-speech.html)


---

## About the author

**Roy Osherove**: Senior Solutions Architect at AWS working on AI for production and AI-driven development; author of The Art of Unit Testing and Elastic Leadership, with about 20 years of consulting and training on unit testing, TDD, team leadership and continuous delivery.

### Sites

- [RobotPaper](https://robotpaper.ai/): This blog: AI patterns and anti-patterns, AI and coding agents, and engineering leadership.
- [osherove.com](https://osherove.com): Roy's personal site. Author of The Art of Unit Testing and Elastic Leadership; consulting and training on unit testing, TDD, team leadership and continuous delivery, plus about 20 years of blog posts.
- [The Art of Unit Testing](https://www.artofunittesting.com): The Art of Unit Testing, 3rd Edition (Manning): readable, maintainable, trustworthy unit tests, plus TDD workshops in C#, JavaScript, Java and Kotlin.
- [5whys.com](https://www.5whys.com): Roy's writing on software team leadership: self-organizing teams, surviving chaos, learning mode and the Elastic Leadership model.
- [Pipeline Driven](https://pipelinedriven.org): Continuous delivery and DevOps practices: build patterns, pipeline-friendly testing, DevOps metrics and enterprise DevOps.
- [Elastic Leadership](https://www.elasticleadership.com): Elastic Leadership, Roy's framework for software team leaders (survival, learning and self-organizing modes).

### Social

- X: https://x.com/royosherove
- LinkedIn: https://www.linkedin.com/in/osherove/

### Contact

- Contact form: https://forms.gle/jQSx5KoXvrVA1JCK7

### License

Licensed under CC BY 4.0 — reuse, quote and adapt with attribution (Roy Osherove, link to the original page). License: https://creativecommons.org/licenses/by/4.0/
