Lazy Compiler使用Syngram动态创建语法分析器的代码实在是太慢了,debug竟然需要8秒钟来处理91条比较长的文法。于是我打开了Visual Studio 2008的Performance Wizard查看运行时消耗的资源,结果发现竟然都消耗在自己那个array类的operator[]里面了。那一段代码是用来检查文法的左递归引用关系是否出现环的。结果就把用到的四个array全部换成bool*了,当时只是为了创建二维数组方便使用了array类。
过后,debug的时间立刻降为2秒钟不到,于是我又打开Performance Wizard看了一次,这次消耗的瓶颈终于转移到一个合理的地方了。
结果:array竟然比指针慢了无穷多倍,得找个时候重新写一次。不过这段代码好象是去年写的,也没经过什么性能测试,也难怪发现不了问题。在此帖上代码,等Lazy Script写完了重新审查一下自己的那套模板库(NTL,Non-standard Template Library,娃哈哈)。
1 enum VLE_ArrayCommander
2 {
3 vacNewArray
4 };
5
6 template<VLE_ArrayCommander _Commander , VInt _Dims>
7 class VL_ArrayDimension : public VL_Base
8 {
9 public:
10 VInt Dims[_Dims+1];
11
12 VL_ArrayDimension()
13 {
14 for(VInt i=0;i<_Dims;i++)
15 {
16 Dims[i]=0;
17 }
18 }
19
20 VL_ArrayDimension(VInt Dim , VInt* PrevDims)
21 {
22 Dims[0]=Dim;
23 memcpy(Dims+1,PrevDims,sizeof(VInt)*(_Dims-1));
24 }
25
26 VL_ArrayDimension<_Commander , _Dims+1> operator [](VInt Dim)
27 {
28 return VL_ArrayDimension<_Commander , _Dims+1>(Dim,Dims);
29 }
30
31 VInt GetSize()
32 {
33 VInt Size=1;
34 for(VInt i=0;i<_Dims;i++)
35 {
36 Size*=Dims[i];
37 }
38 return Size;
39 }
40 };
41
42 extern VL_ArrayDimension<vacNewArray , 0> NewArray;
43
44 template<typename _Type>
45 class VL_ArrayInfo : public VL_Base
46 {
47 public:
48 _Type* Elements;
49 VInt* Dims;
50 VInt RefCount;
51 VInt Size;
52
53 VL_ArrayInfo(VInt aDims)
54 {
55 Dims=new VInt[aDims];
56 }
57
58 ~VL_ArrayInfo()
59 {
60 delete[] Dims;
61 }
62 };
63
64 template<typename _Type , VInt _Dims>
65 class VL_Array : public VL_Base
66 {
67 protected:
68
69 public:
70
71 template<VInt _RefDims>
72 class VL_ArrayReference : public VL_Base
73 {
74 friend class VL_Array;
75 protected:
76 VL_ArrayInfo<_Type>* FInfo;
77 _Type* FElements;
78 VInt FSubSize;
79 public:
80
81 VL_ArrayReference(_Type* Elements , VL_ArrayInfo<_Type>* Info , VInt Dim)
82 {
83 FInfo=Info;
84 FSubSize=FInfo->Size/FInfo->Dims[_RefDims];
85 FElements=Elements+Dim*FSubSize;
86 }
87
88 VL_ArrayReference(VL_ArrayInfo<_Type>* Info , _Type* Elements , VInt SubSize)
89 {
90 FInfo=Info;
91 FElements=Elements;
92 FSubSize=SubSize;
93 }
94
95 VL_ArrayReference<_RefDims-1> operator [](VInt Dim)
96 {
97 VInt SubSize=FSubSize/FInfo->Dims[_RefDims-1];
98 return VL_ArrayReference<_RefDims-1>(FInfo,FElements+Dim*SubSize,SubSize);
99 }
100
101 operator VL_Array<_Type , _RefDims>()
102 {
103 return VL_Array<_Type , _Dims-1>(FInfo,FElements);
104 }
105
106 VL_Array<_Type , _RefDims> Reference()
107 {
108 return VL_Array<_Type , _Dims-1>(FInfo,FElements);
109 }
110
111 VL_Array<_Type , _RefDims> Clone()
112 {
113 return VL_Array<_Type , _Dims-1>(FInfo,FElements).Clone();
114 }
115
116 void Copy(VL_Array<_Type , _RefDims>& Array)
117 {
118 VL_ArrayInfo<_Type>* ArrayInfo=Array.GetInfo();
119 VInt Count=FInfo->Dims[_RefDims-1];
120 if(Count>ArrayInfo->Dims[_RefDims-1])
121 {
122 Count=ArrayInfo->Dims[_RefDims-1];
123 }
124 for(VInt i=0;i<Count;i++)
125 {
126 operator [](i).Copy(Array[i].Reference());
127 }
128 }
129
130 VInt GetCount()
131 {
132 return FInfo->Dims[_RefDims-1];
133 }
134 };
135
136 template<>
137 class VL_ArrayReference<1> : public VL_Base
138 {
139 protected:
140 VL_ArrayInfo<_Type>* FInfo;
141 _Type* FElements;
142 public:
143
144 VL_ArrayReference(_Type* Elements , VL_ArrayInfo<_Type>* Info , VInt Dim)
145 {
146 FInfo=Info;
147 FElements=Elements+Dim*FInfo->Size/FInfo->Dims[1];
148 }
149
150 VL_ArrayReference(VL_ArrayInfo<_Type>* Info , _Type* Elements , VInt SubSize)
151 {
152 FInfo=Info;
153 FElements=Elements;
154 }
155
156 _Type& operator [](VInt Dim)
157 {
158 return FElements[Dim];
159 }
160
161 operator VL_Array<_Type , 1>()
162 {
163 return VL_Array<_Type , 1>(FInfo,FElements);
164 }
165
166 VL_Array<_Type , 1> Reference()
167 {
168 return VL_Array<_Type , 1>(FInfo,FElements);
169 }
170
171 VL_Array<_Type , 1> Clone()
172 {
173 return VL_Array<_Type , 1>(FInfo,FElements).Clone();
174 }
175
176 void Copy(VL_Array<_Type , 1>& Array)
177 {
178 VL_ArrayInfo<_Type>* ArrayInfo=Array.GetInfo();
179 _Type* ArrayElements=Array.GetElements();
180 VInt Count=FInfo->Dims[0];
181 if(Count>ArrayInfo->Dims[0])
182 {
183 Count=ArrayInfo->Dims[0];
184 }
185 for(VInt i=0;i<Count;i++)
186 {
187 FElements[i]=ArrayElements[i];
188 }
189 }
190
191 VInt GetCount()
192 {
193 return FInfo->Dims[0];
194 }
195 };
196
197 protected:
198 VL_ArrayInfo<_Type>* FInfo;
199 _Type* FElements;
200
201 void Create(VInt Size)
202 {
203 FInfo=new VL_ArrayInfo<_Type>(_Dims);
204 FInfo->Elements=new _Type[Size];
205 FInfo->RefCount=1;
206 FInfo->Size=Size;
207 if(Size==0)
208 {
209 for(VInt i=0;i<_Dims;i++)
210 {
211 FInfo->Dims[i]=0;
212 }
213 }
214 FElements=FInfo->Elements;
215 }
216
217 void Inc()
218 {
219 FInfo->RefCount++;
220 }
221
222 void Dec()
223 {
224 if(!--FInfo->RefCount)
225 {
226 delete[] FInfo->Elements;
227 delete FInfo;
228 FInfo=0;
229 FElements=0;
230 }
231 }
232
233 VL_Array(VInt Size)
234 {
235 Create(Size);
236 }
237
238 public:
239
240 VL_Array()
241 {
242 Create(0);
243 }
244
245 VL_Array(VL_ArrayInfo<_Type>* Info , _Type* Elements)
246 {
247 FInfo=Info;
248 FElements=Elements;
249 Inc();
250 }
251
252 VL_Array(VL_ArrayDimension<vacNewArray , _Dims>& Dims)
253 {
254 Create(Dims.GetSize());
255 memcpy(FInfo->Dims,Dims.Dims,sizeof(VInt)*_Dims);
256 }
257
258 ~VL_Array()
259 {
260 Dec();
261 }
262
263 VL_Array(VL_Array<_Type , _Dims>& Array)
264 {
265 FInfo=Array.FInfo;
266 FElements=Array.FElements;
267 Inc();
268 }
269
270 VL_Array<_Type , _Dims>& operator =(VL_Array<_Type , _Dims>& Array)
271 {
272 Dec();
273 FInfo=Array.FInfo;
274 FElements=Array.FElements;
275 Inc();
276 return *this;
277 }
278
279 VL_ArrayReference<_Dims-1> operator [](VInt Dim)
280 {
281 return VL_ArrayReference<_Dims-1>(FElements,FInfo,Dim);
282 }
283
284 VL_Array<_Type , _Dims> Reference()
285 {
286 return *this;
287 }
288
289 VL_Array<_Type , _Dims> Clone()
290 {
291 VL_Array<_Type , _Dims> Array(FInfo->Size);
292 for(VInt i=0;i<FInfo->Size;i++)
293 {
294 Array.FElements[i]=FElements[i];
295 }
296 memcpy(Array.FInfo->Dims,FInfo->Dims,sizeof(VInt)*_Dims);
297 return Array;
298 };
299
300 void Copy(VL_Array<_Type , _Dims>& Array)
301 {
302 operator =(Array.Clone());
303 }
304
305 VL_ArrayInfo<_Type>* GetInfo()
306 {
307 return FInfo;
308 }
309
310 _Type* GetElements()
311 {
312 return FElements;
313 }
314
315 VInt GetCount()
316 {
317 return FInfo->Dims[_Dims-1];
318 }
319 };
320
321 template<typename _Type>
322 class VL_Array<_Type , 1> : public VL_Base
323 {
324 protected:
325 VL_ArrayInfo<_Type>* FInfo;
326 _Type* FElements;
327
328 void Create(VInt Size)
329 {
330 FInfo=new VL_ArrayInfo<_Type>(1);
331 FInfo->Elements=new _Type[Size];
332 FInfo->RefCount=1;
333 FInfo->Size=Size;
334 FInfo->Dims[0]=0;
335 FElements=FInfo->Elements;
336 }
337
338 void Inc()
339 {
340 FInfo->RefCount++;
341 }
342
343 void Dec()
344 {
345 if(!--FInfo->RefCount)
346 {
347 delete[] FInfo->Elements;
348 delete FInfo;
349 FInfo=0;
350 FElements=0;
351 }
352 }
353
354 VL_Array(VInt Size)
355 {
356 Create(Size);
357 }
358
359 public:
360
361 VL_Array()
362 {
363 Create(0);
364 }
365
366 VL_Array(VL_ArrayInfo<_Type>* Info , _Type* Elements)
367 {
368 FInfo=Info;
369 FElements=Elements;
370 Inc();
371 }
372
373 VL_Array(VL_ArrayDimension<vacNewArray , 1>& Dims)
374 {
375 Create(Dims.GetSize());
376 FInfo->Dims[0]=Dims.Dims[0];
377 }
378
379 ~VL_Array()
380 {
381 Dec();
382 }
383
384 VL_Array(VL_Array<_Type , 1>& Array)
385 {
386 FInfo=Array.FInfo;
387 FElements=Array.FElements;
388 Inc();
389 }
390
391 VL_Array<_Type , 1>& operator =(VL_Array<_Type , 1>& Array)
392 {
393 Dec();
394 FInfo=Array.FInfo;
395 FElements=Array.FElements;
396 Inc();
397 return *this;
398 }
399
400 _Type& operator [](VInt Dim)
401 {
402 return FInfo->Elements[Dim];
403 }
404
405 VL_Array<_Type , 1> Reference()
406 {
407 return *this;
408 }
409
410 VL_Array<_Type , 1> Clone()
411 {
412 VL_Array<_Type , 1> Array(FInfo->Size);
413 for(VInt i=0;i<FInfo->Size;i++)
414 {
415 Array.FInfo->Elements[i]=FInfo->Elements[i];
416 }
417 return Array;
418 };
419
420 void Copy(VL_Array<_Type , 1>& Array)
421 {
422 operator =(Array.Clone());
423 }
424
425 VL_ArrayInfo<_Type>* GetInfo()
426 {
427 return FInfo;
428 }
429
430 _Type* GetElements()
431 {
432 return FElements;
433 }
434
435 VInt GetCount()
436 {
437 return FInfo->Dims[0];
438 }
439 };
posted on 2008-04-27 19:53
陈梓瀚(vczh) 阅读(2621)
评论(6) 编辑 收藏 引用 所属分类:
C++