root/OpenSceneGraph/trunk/examples/osgunittests/performance.cpp @ 6941

Revision 6941, 6.1 kB (checked in by robert, 8 years ago)

From Martin Lavery and Robert Osfield, Updated examples to use a variation of the MIT License

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* OpenSceneGraph example, osgunittests.
2*
3*  Permission is hereby granted, free of charge, to any person obtaining a copy
4*  of this software and associated documentation files (the "Software"), to deal
5*  in the Software without restriction, including without limitation the rights
6*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7*  copies of the Software, and to permit persons to whom the Software is
8*  furnished to do so, subject to the following conditions:
9*
10*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16*  THE SOFTWARE.
17*/
18
19#include "performance.h"
20
21#include <osg/Timer>
22#include <iostream>
23
24#include <osg/NodeVisitor>
25#include <osg/ref_ptr>
26#include <osg/MatrixTransform>
27#include <osg/Group>
28
29struct Benchmark
30{
31
32    Benchmark()
33    {
34        calibrate();
35   
36        _beginTick = _timer.tick();
37        _endTick = _timer.tick();
38    }
39   
40    void calibrate(unsigned int numLoops = 100000)
41    {
42        osg::Timer_t beginTick = _timer.tick();
43        for(unsigned int i=0;i<numLoops;++i)
44        {
45            begin();
46            end();
47        }
48        osg::Timer_t endTick = _timer.tick();
49        _averageDelay = _timer.delta_s(beginTick,endTick)/(double)numLoops;
50    }
51   
52    inline void begin()
53    {
54        _beginTick = _timer.tick();
55    }
56
57    inline void end()
58    {
59        _endTick = _timer.tick();
60    }
61
62    inline double time()
63    {
64        double t = _timer.delta_s(_beginTick,_endTick) - _averageDelay;
65        return t<0.0 ? 0.0 : t;
66    }
67
68    inline void output(const char* str, double numIterations=1.0)
69    {
70        std::cout<<str<<"\t";
71        double s = time()/numIterations;
72        if (s>=1.0) std::cout<<s<<" s"<<std::endl;
73        else if (s>=0.001) std::cout<<s*1000.0<<" ms (10 ^ -3)"<<std::endl;
74        else if (s>=0.000001) std::cout<<s*1000000.0<<" ns (10 ^ -6)"<<std::endl;
75        else std::cout<<s*1000000000.0<<" ps (10 ^ -9)"<<std::endl;
76    }
77
78    osg::Timer   _timer;
79    osg::Timer_t _beginTick;
80    osg::Timer_t _endTick;
81    double _averageDelay;
82};
83
84#define RUN(A,B,D) { A.begin(); for(unsigned int i=0;i<D;++i) B; A.end(); A.output(#B,D); }
85
86
87static int v = 0;
88#define OPERATION { v=v+1; }
89
90inline void inline_increment() { OPERATION }
91void function_increment() { OPERATION }
92
93typedef void ( * IncrementProc) ();
94IncrementProc s_functionIncrement = &function_increment;
95inline void functionPointer_increment() { s_functionIncrement(); }
96
97
98struct InlineMethod;
99struct Method;
100struct VirtualMethod;
101struct VirtualMethod2;
102
103struct Visitor
104{
105    virtual void apply(InlineMethod& m);
106    virtual void apply(Method& m);
107    virtual void apply(VirtualMethod& m);
108    virtual void apply(VirtualMethod2& m);
109    virtual ~Visitor() {}
110};
111
112
113struct InlineMethod
114{
115    void method() { OPERATION }
116    virtual void accept(Visitor& visitor) { visitor.apply(*this); }
117    virtual ~InlineMethod() {}
118};
119
120struct Method
121{
122    virtual void accept(Visitor& visitor) { visitor.apply(*this); }
123    void method();
124    virtual ~Method() {}
125};
126
127void Method::method() { OPERATION }
128 
129struct VirtualMethod
130{
131    virtual void accept(Visitor& visitor) { visitor.apply(*this); }
132    virtual void method();
133    virtual ~VirtualMethod() {}
134};
135
136void VirtualMethod::method() { OPERATION }
137
138struct VirtualMethod2 : public VirtualMethod
139{
140    VirtualMethod2() { }
141
142    virtual void accept(Visitor& visitor) { visitor.apply(*this); }
143    virtual void method();
144    virtual ~VirtualMethod2() { }
145   
146    char a[100];
147};
148
149void VirtualMethod2::method() { OPERATION }
150
151void Visitor::apply(Method& m) { m.method(); }
152void Visitor::apply(VirtualMethod& m) { m.method(); }
153void Visitor::apply(InlineMethod& m) { m.method(); }
154void Visitor::apply(VirtualMethod2& m) { m.method(); }
155
156struct CustomVisitor
157{
158    virtual void apply(InlineMethod& m) { m.method(); }
159    virtual void apply(Method& m) { m.method(); }
160    virtual void apply(VirtualMethod& m) { m.method(); }
161    virtual void apply(VirtualMethod2& m) { m.method(); }
162    virtual ~CustomVisitor() {}
163};
164
165class CustomNodeVisitor : public osg::NodeVisitor
166{
167public:
168    void apply(osg::Node&) { }
169    void apply(osg::Group&) { }
170    void apply(osg::Transform&) { }
171};
172
173
174void runPerformanceTests()
175{
176    Benchmark benchmark;
177   
178    unsigned int iterations = 10000000;
179
180    RUN(benchmark, {} , iterations)
181
182    v = 0;
183    RUN(benchmark, OPERATION , iterations)
184    RUN(benchmark, functionPointer_increment() , iterations)
185    RUN(benchmark, inline_increment() , iterations)
186    RUN(benchmark, function_increment() , iterations)
187
188    VirtualMethod2 m4;
189    RUN(benchmark, m4.method() , iterations)
190
191    InlineMethod m1;
192    RUN(benchmark, m1.method() , iterations)
193
194    Method m2;
195    RUN(benchmark, m2.method() , iterations)
196
197    VirtualMethod m3;
198    RUN(benchmark, m3.method() , iterations)
199    RUN(benchmark, m3.method() , iterations)
200
201    Visitor visitor;
202    RUN(benchmark, m4.accept(visitor), iterations)
203    RUN(benchmark, m1.accept(visitor), iterations)
204    RUN(benchmark, m2.accept(visitor), iterations)
205    RUN(benchmark, m3.accept(visitor), iterations)
206    RUN(benchmark, m4.accept(visitor), iterations)
207
208    VirtualMethod* vm4 = &m4;
209
210    RUN(benchmark, (dynamic_cast<VirtualMethod2*>(vm4))->method(), iterations)
211    RUN(benchmark, (static_cast<VirtualMethod2*>(vm4))->method(), iterations)
212    RUN(benchmark, { VirtualMethod mm; mm.method(); }, iterations)
213    RUN(benchmark, { VirtualMethod2 mm; mm.method(); }, iterations)
214
215
216    osg::ref_ptr<osg::Group> group = new osg::Group;
217    osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;
218    osg::Node* m = mt.get();
219    CustomNodeVisitor cnv;
220    RUN(benchmark, { osg::MatrixTransform* mtl = dynamic_cast<osg::MatrixTransform*>(m); if (mtl) cnv.apply(*mtl); }, 1000)
221    RUN(benchmark, { m->accept(cnv); }, 10000)
222   
223}
Note: See TracBrowser for help on using the browser.