blob: 2fad7fcf4dea2acf96f4fc0dfb0892507c43f223 [file] [log] [blame]
bsalomon@google.com4da34e32012-06-19 15:40:27 +00001/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "GrMemoryPool.h"
9#include "SkBenchmark.h"
10#include "SkRandom.h"
11#include "SkTScopedPtr.h"
12#include "SkTDArray.h"
13
14// change this to 0 to compare GrMemoryPool to default new / delete
15#define OVERRIDE_NEW 1
16
17namespace {
18struct A {
19 int gStuff[10];
20#if OVERRIDE_NEW
21 void* operator new (size_t size) { return gPool.allocate(size); }
22 void operator delete (void* mem) { if (mem) { return gPool.release(mem); } }
23#endif
24 static GrMemoryPool gPool;
25};
26GrMemoryPool A::gPool(10 * (1 << 10), 10 * (1 << 10));
27}
28
29
30/**
31 * This benchmark creates and deletes objects in stack order
32 */
33class GrMemoryPoolBenchStack : public SkBenchmark {
34 enum {
35 N = SkBENCHLOOP(5 * (1 << 20)),
36 };
37public:
38 GrMemoryPoolBenchStack(void* param) : INHERITED(param) {
39 }
40protected:
41 virtual const char* onGetName() {
42 return "grmemorypool_stack";
43 }
44
45 virtual void onDraw(SkCanvas* canvas) {
46 SkRandom r;
47 enum {
48 kMaxObjects = 4 * (1 << 10),
49 };
50 A* objects[kMaxObjects];
51
52 // We delete if a random [-1, 1] fixed pt is < the thresh. Otherwise,
53 // we allocate. We start allocate-biased and ping-pong to delete-biased
54 SkFixed delThresh = -SK_FixedHalf;
55 enum {
56 kSwitchThreshPeriod = N / (2 * kMaxObjects),
57 };
58 int s = 0;
59
60 int count = 0;
61 for (int i = 0; i < N; i++, ++s) {
62 if (kSwitchThreshPeriod == s) {
63 delThresh = -delThresh;
64 s = 0;
65 }
66 SkFixed del = r.nextSFixed1();
67 if (count &&
68 (kMaxObjects == count || del < delThresh)) {
69 delete objects[count-1];
70 --count;
71 } else {
72 objects[count] = new A;
73 ++count;
74 }
75 }
76 for (int i = 0; i < count; ++i) {
77 delete objects[i];
78 }
79 }
80
81private:
82 typedef SkBenchmark INHERITED;
83};
84
85/**
86 * This benchmark creates objects and deletes them in random order
87 */
88class GrMemoryPoolBenchRandom : public SkBenchmark {
89 enum {
90 N = SkBENCHLOOP(5 * (1 << 20)),
91 };
92public:
93 GrMemoryPoolBenchRandom(void* param) : INHERITED(param) {
94 }
95protected:
96 virtual const char* onGetName() {
97 return "grmemorypool_random";
98 }
99
100 virtual void onDraw(SkCanvas* canvas) {
101 SkRandom r;
102 enum {
103 kMaxObjects = 4 * (1 << 10),
104 };
105 SkTScopedPtr<A> objects[kMaxObjects];
106
107 for (int i = 0; i < N; i++) {
108 uint32_t idx = r.nextRangeU(0, kMaxObjects-1);
109 if (NULL == objects[idx].get()) {
110 objects[idx].reset(new A);
111 } else {
112 objects[idx].reset(NULL);
113 }
114 }
115 }
116
117private:
118 typedef SkBenchmark INHERITED;
119};
120
121/**
122 * This benchmark creates objects and deletes them in queue order
123 */
124class GrMemoryPoolBenchQueue : public SkBenchmark {
125 enum {
126 N = SkBENCHLOOP((1 << 10)),
127 M = SkBENCHLOOP(4 * (1 << 10)),
128 };
129public:
130 GrMemoryPoolBenchQueue(void* param) : INHERITED(param) {
131 }
132protected:
133 virtual const char* onGetName() {
134 return "grmemorypool_queue";
135 }
136
137 virtual void onDraw(SkCanvas* canvas) {
138 SkRandom r;
139 A* objects[M];
140 for (int i = 0; i < N; i++) {
141 uint32_t count = r.nextRangeU(0, M-1);
142 for (uint32_t i = 0; i < count; i++) {
143 objects[i] = new A;
144 }
145 for (uint32_t i = 0; i < count; i++) {
146 delete objects[i];
147 }
148 }
149 }
150
151private:
152 typedef SkBenchmark INHERITED;
153};
154
155///////////////////////////////////////////////////////////////////////////////
156
157static SkBenchmark* Fact1(void* p) { return new GrMemoryPoolBenchStack(p); }
158static SkBenchmark* Fact2(void* p) { return new GrMemoryPoolBenchRandom(p); }
159static SkBenchmark* Fact3(void* p) { return new GrMemoryPoolBenchQueue(p); }
160
161static BenchRegistry gReg01(Fact1);
162static BenchRegistry gReg02(Fact2);
163static BenchRegistry gReg03(Fact3);
164