OLD | NEW |
---|---|
(Empty) | |
1 #include "SkBenchmark.h" | |
caryclark
2014/01/06 22:05:21
copyright at top?
mtklein_C
2014/01/07 15:41:14
Done.
| |
2 #include "SkRandom.h" | |
caryclark
2014/01/06 22:05:21
alphabetized?
mtklein_C
2014/01/07 15:41:14
Was trying to keep support code and data-structure
| |
3 | |
4 #include "SkChunkAlloc.h" | |
5 #include "SkDeque.h" | |
6 #include "SkTArray.h" | |
7 #include "SkTDArray.h" | |
8 | |
9 // This file has several benchmarks using various data structures to do stack-li ke things: | |
10 // - push | |
11 // - push, immediately pop | |
12 // - push many, pop all of them | |
13 // - serial access | |
14 // - random access | |
15 // When a data structure doesn't suppport an operation efficiently, we leave tha t combination out. | |
16 // Where possible we hint to the data structure to allocate in 4K pages. | |
17 // | |
18 // These benchmarks may help you decide which data structure to use for a dynami cally allocated | |
19 // ordered list of allocations that grows on one end. | |
20 // | |
21 // Current overall winner (01/2014): SkTDArray. | |
22 // It wins every benchmark on every machine I tried (Desktop, Nexus S, Laptop). | |
23 | |
24 template <typename Impl> | |
25 struct StackBench : public SkBenchmark { | |
26 virtual bool isSuitableFor(Backend b) SK_OVERRIDE { return b == kNonRenderin g_Backend; } | |
27 virtual const char* onGetName() SK_OVERRIDE { return Impl::kName; } | |
28 virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE { Impl::bench(lo ops); } | |
29 }; | |
30 | |
31 #define BENCH(name) \ | |
32 struct name { static const char* const kName; static void bench(int); }; \ | |
33 const char* const name::kName = #name; \ | |
34 DEF_BENCH(return new StackBench<name>();) \ | |
35 void name::bench(int loops) | |
36 | |
37 static const int K = 2049; | |
38 | |
39 // Add K items, then iterate through them serially many times. | |
40 | |
41 BENCH(Deque_Serial) { | |
42 SkDeque s(sizeof(int), 1024); | |
43 for (int i = 0; i < K; i++) *(int*)s.push_back() = i; | |
44 | |
45 volatile int junk = 0; | |
46 for (int j = 0; j < loops; j++) { | |
47 SkDeque::Iter it(s, SkDeque::Iter::kFront_IterStart); | |
48 while(void* p = it.next()) { | |
caryclark
2014/01/06 22:05:21
some compilers are going to want extra parens here
mtklein_C
2014/01/07 15:41:14
I think this will be OK. Clang, who usually wants
| |
49 junk += *(int*)p; | |
50 } | |
51 } | |
52 } | |
53 | |
54 BENCH(TArray_Serial) { | |
55 SkTArray<int, true> s; | |
56 for (int i = 0; i < K; i++) s.push_back(i); | |
57 | |
58 volatile int junk = 0; | |
59 for (int j = 0; j < loops; j++) { | |
60 for (int i = 0; i < s.count(); i++) junk += s[i]; | |
61 } | |
62 } | |
63 | |
64 BENCH(TDArray_Serial) { | |
65 SkTDArray<int> s; | |
66 for (int i = 0; i < K; i++) s.push(i); | |
67 | |
68 volatile int junk = 0; | |
69 for (int j = 0; j < loops; j++) { | |
70 for (int i = 0; i < s.count(); i++) junk += s[i]; | |
71 } | |
72 } | |
73 | |
74 // Add K items, then randomly access them many times. | |
75 | |
76 BENCH(TArray_RandomAccess) { | |
77 SkTArray<int, true> s; | |
78 for (int i = 0; i < K; i++) s.push_back(i); | |
79 | |
80 SkRandom rand; | |
81 volatile int junk = 0; | |
82 for (int i = 0; i < K*loops; i++) { | |
83 junk += s[rand.nextULessThan(K)]; | |
84 } | |
85 } | |
86 | |
87 BENCH(TDArray_RandomAccess) { | |
88 SkTDArray<int> s; | |
89 for (int i = 0; i < K; i++) s.push(i); | |
90 | |
91 SkRandom rand; | |
92 volatile int junk = 0; | |
93 for (int i = 0; i < K*loops; i++) { | |
94 junk += s[rand.nextULessThan(K)]; | |
95 } | |
96 } | |
97 | |
98 // Push many times. | |
99 | |
100 BENCH(ChunkAlloc_Push) { | |
101 SkChunkAlloc s(4096); | |
102 for (int i = 0; i < K*loops; i++) s.allocThrow(sizeof(int)); | |
103 } | |
104 | |
105 BENCH(Deque_Push) { | |
106 SkDeque s(sizeof(int), 1024); | |
107 for (int i = 0; i < K*loops; i++) *(int*)s.push_back() = i; | |
108 } | |
109 | |
110 BENCH(TArray_Push) { | |
111 SkTArray<int, true> s; | |
112 for (int i = 0; i < K*loops; i++) s.push_back(i); | |
113 } | |
114 | |
115 BENCH(TDArray_Push) { | |
116 SkTDArray<int> s; | |
117 for (int i = 0; i < K*loops; i++) s.push(i); | |
118 } | |
119 | |
120 // Push then immediately pop many times. | |
121 | |
122 BENCH(ChunkAlloc_PushPop) { | |
123 SkChunkAlloc s(4096); | |
124 for (int i = 0; i < K*loops; i++) { | |
125 void* p = s.allocThrow(sizeof(int)); | |
126 s.unalloc(p); | |
127 } | |
128 } | |
129 | |
130 BENCH(Deque_PushPop) { | |
131 SkDeque s(sizeof(int), 1024); | |
132 for (int i = 0; i < K*loops; i++) { | |
133 *(int*)s.push_back() = i; | |
134 s.pop_back(); | |
135 } | |
136 } | |
137 | |
138 BENCH(TArray_PushPop) { | |
139 SkTArray<int, true> s; | |
140 for (int i = 0; i < K*loops; i++) { | |
141 s.push_back(i); | |
142 s.pop_back(); | |
143 } | |
144 } | |
145 | |
146 BENCH(TDArray_PushPop) { | |
147 SkTDArray<int> s; | |
148 for (int i = 0; i < K*loops; i++) { | |
149 s.push(i); | |
150 s.pop(); | |
151 } | |
152 } | |
153 | |
154 // Push many items, then pop them all. | |
155 | |
156 BENCH(Deque_PushAllPopAll) { | |
157 SkDeque s(sizeof(int), 1024); | |
158 for (int i = 0; i < K*loops; i++) *(int*)s.push_back() = i; | |
159 for (int i = 0; i < K*loops; i++) s.pop_back(); | |
160 } | |
161 | |
162 BENCH(TArray_PushAllPopAll) { | |
163 SkTArray<int, true> s; | |
164 for (int i = 0; i < K*loops; i++) s.push_back(i); | |
165 for (int i = 0; i < K*loops; i++) s.pop_back(); | |
166 } | |
167 | |
168 BENCH(TDArray_PushAllPopAll) { | |
169 SkTDArray<int> s; | |
170 for (int i = 0; i < K*loops; i++) s.push(i); | |
171 for (int i = 0; i < K*loops; i++) s.pop(); | |
172 } | |
OLD | NEW |