Commit 8902ae89 authored by Julien Finet's avatar Julien Finet
Browse files

Add performance test for vtkObject observations

Change-Id: Ia9af47bbe7946da67e67c65ef38c2c3fd4171ba7
parent fd6f500c
......@@ -23,6 +23,7 @@ create_test_sourcelist(Tests ${vtk-module}CxxTests.cxx
TestNew.cxx
TestObjectFactory.cxx
TestObservers.cxx
TestObserversPerformance.cxx
TestSmartPointer.cxx
TestSortDataArray.cxx
TestSparseArrayValidation.cxx
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestSmartPointer.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// .NAME Test speed of Observers.
// .SECTION Description
// Probe the speed of vtkObject::AddObserver, vtkObject::InvokeEvent and
// vtkObject::RemoveObserver
#include "vtkCollection.h"
#include "vtkCommand.h"
#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkSmartPointer.h"
#include "vtkTimerLog.h"
#include <map>
#include <vector>
// How many times the tests are run to average the elapsed time.
const int STRESS_COUNT = 5;
// Description:
// Type of console outputs.
// CDash writes perfs as <DartMeasurement ...> for unit test regression
// Csv writes perfs as series of 2D table for easy plotting in spreadsheet apps
// Details writes more timing information
enum VerboseType
{
None = 0x0,
CDash = 0x1,
Csv = 0x2,
Details = 0x4
};
const int VERBOSE_MODE = CDash;
//------------------------------------------------------------------------------
class vtkSimpleCommand : public vtkCommand
{
public:
static vtkSimpleCommand* New() { return new vtkSimpleCommand();}
vtkTypeMacro(vtkSimpleCommand, vtkCommand);
virtual void Execute(vtkObject*, unsigned long event, void*)
{
this->MTime.Modified();
}
protected:
static vtkTimeStamp MTime;
};
vtkTimeStamp vtkSimpleCommand::MTime;
//------------------------------------------------------------------------------
double TestStressInvoke(int observerCount, int eventCount, int invokeCount);
//------------------------------------------------------------------------------
int TestObserversPerformance(int, char*[])
{
bool res = true;
int maxInvokeCount = 1000;
int maxEventCount = 100;
int maxObserverCount = 1000;
for (int eventCount = 1; eventCount <= maxEventCount; eventCount *= 10)
{
if (VERBOSE_MODE & Csv)
{
std::cout << eventCount << " events:" << "\n" << ",";
for (int observerCount = 1; observerCount <= maxObserverCount; observerCount *= 10)
{
std::cout << observerCount << ",";
}
std::cout << std::endl;
}
for (int invokeCount = 1; invokeCount <= maxInvokeCount; invokeCount *= 10)
{
if (VERBOSE_MODE & Csv)
{
std::cout << invokeCount << ",";
}
for (int observerCount = 1; observerCount <= maxObserverCount; observerCount *= 10)
{
double time = TestStressInvoke(observerCount, eventCount, invokeCount);
if (VERBOSE_MODE & Csv)
{
std::cout << time << ",";
}
}
if (VERBOSE_MODE & Csv)
{
std::cout << std::endl;
}
}
}
return EXIT_SUCCESS;
}
//------------------------------------------------------------------------------
double StressInvoke(const int observerCount, const int eventCount, const int invokeCount)
{
if (VERBOSE_MODE & Details)
{
std::cout << "StressInvoke " << invokeCount << " invokes "
<< "on " << eventCount << " events observed by "
<< observerCount / eventCount << " observers each." << std::endl;
}
vtkObject* volcano = vtkObject::New();
std::vector<vtkSmartPointer<vtkSimpleCommand> > observers;
vtkNew<vtkTimerLog> totalTimer;
vtkNew<vtkTimerLog> addTimer;
vtkNew<vtkTimerLog> invokeTimer;
vtkNew<vtkTimerLog> removeTimer;
totalTimer->StartTimer();
addTimer->StartTimer();
for (int observer = 0; observer < observerCount; observer += eventCount)
{
for (int event = 0; event < eventCount; ++event)
{
vtkNew<vtkSimpleCommand> observer;
volcano->AddObserver(event + 1000, observer.GetPointer());
observers.push_back(observer.GetPointer());
}
}
addTimer->StopTimer();
invokeTimer->StartTimer();
for (int invoke = 0; invoke < invokeCount; invoke += eventCount)
{
for (int event = 0; event < eventCount; ++event)
{
volcano->InvokeEvent(event + 1000);
}
}
invokeTimer->StopTimer();
removeTimer->StartTimer();
observers.clear();
volcano->Delete();
removeTimer->StopTimer();
totalTimer->StopTimer();
if (VERBOSE_MODE & Details)
{
std::cout << " Add: " << addTimer->GetElapsedTime() << " seconds" << "\n"
<< " Invoke: " << invokeTimer->GetElapsedTime() << " seconds" << "\n"
<< " Remove: " << removeTimer->GetElapsedTime() << " seconds" << "\n"
<< ">>>> Total: " << totalTimer->GetElapsedTime() << " seconds" << "\n";
}
return totalTimer->GetElapsedTime();
}
//------------------------------------------------------------------------------
double TestStressInvoke(int observerCount, int eventCount, int invokeCount)
{
double meanDuration = 0.0;
for (int i = 0; i < STRESS_COUNT; ++i)
{
meanDuration += StressInvoke(observerCount, eventCount, invokeCount);
}
meanDuration /= STRESS_COUNT;
if (VERBOSE_MODE == CDash)
{
std::cout << "<DartMeasurement name=\"StressInvoke-"
<< observerCount << "-" << eventCount << "-" << invokeCount
<< "\" type=\"numeric/double\">"
<< meanDuration << "</DartMeasurement>" << std::endl;
}
return meanDuration;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment