wwwtc2.htm
来自「C++builder学习资料C++builder」· HTM 代码 · 共 114 行
HTM
114 行
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE>What's Wrong With This Code? Volume #2</TITLE>
<META content="text/html; charset=gb2312" http-equiv=Content-Type>
<META content="Harold Howe" name=Author>
<META content="Microsoft FrontPage 4.0" name=GENERATOR></HEAD>
<BODY>
<CENTER>
<TABLE border=0 cellPadding=0 cellSpacing=0 width=640>
<TBODY>
<TR>
<TD>
<H2>What's Wrong With This Code? Volume #2 </H2>
<H4>A benchmark gone bad </H4>
<P>About a year or so ago, I wrote a program that benchmarks the
performance of <TT>dynamic_cast</TT> against <TT>__classid</TT> and
<TT>ClassNameIs</TT>. Recently, fellow TeamB'er Chris Uzdavinis asked me
how the performance of <TT>ClassNameIs</TT> compares with
<TT>dynamic_cast</TT>. I told him that it was almost 10 times slower,
based on my benchmark from a long time ago. </P>
<P>After making such a bold response, I decided that I better dig up my
old benchmark and verify that my answer was correct. My benchmark is a
simple, one form program. The main form has 16 controls on it, three of
which are buttons. Each button has an <TT>OnClick</TT> handler. One button
runs a time test on <TT>dynamic_cast</TT>, while the other two buttons
test <TT>__classid</TT> and <TT>ClassNameIs</TT>. </P>
<P>Each button click works in essentially the same way. First, the handler
records the windows clock time with <TT>GetTickCount</TT>. Then, we enter
a for loop that will execute one million times. Inside the mega-loop is
another loop. This loop iterates through all of the components in the
<TT>Components</TT> array of the form. The code calls uses either
<TT>dynamic_cast</TT>, <TT>ClassNameIs</TT>, or <TT>__classid</TT> to
determine whether the component is a <TT>TEdit</TT> control. If the
component is a <TT>TEdit</TT>, then it is manipulated in some way. The
manipulation never occurs though, because none of the controls on the form
are a <TT>TEdit</TT> control. I did this because I want to benchmark the
runtime cast, and not the manipulation of an edit control. </P>
<P>The code for the three <TT>OnClick</TT> handlers is shown below. Figure
1 shows what the mainform looks like after I run the benchmark. The
numbers next to the buttons represent the number of milli-seconds that
each test took. </P><PRE><FONT color=navy>//-----------------------------------------------------------------</FONT>
<FONT color=navy>// Benchmark for __classid</FONT>
<B>void</B> <B>__fastcall</B> TForm1<B>:</B><B>:</B>Button1Click<B>(</B>TObject <B>*</B>Sender<B>)</B>
<B>{</B>
<B>int</B> nCount <B>=</B> ComponentCount<B>;</B>
DWORD dwStart <B>=</B> GetTickCount<B>(</B><B>)</B><B>;</B>
<B>for</B> <B>(</B><B>int</B> j<B>=</B><FONT color=blue>0</FONT><B>;</B> j<<FONT color=blue>1000000</FONT><B>;</B> j<B>++</B><B>)</B>
<B>{</B>
<B>for</B> <B>(</B><B>int</B> i<B>=</B><FONT color=blue>0</FONT><B>;</B> i<nCount<B>;</B> i<B>++</B><B>)</B>
<B>{</B>
<B>if</B><B>(</B>Components<B>[</B>i<B>]</B><B>-></B>ClassType<B>(</B><B>)</B> <B>==</B> <B>__classid</B><B>(</B>TEdit<B>)</B><B>)</B>
<B>(</B><B>(</B>TEdit <B>*</B><B>)</B>Components<B>[</B>i<B>]</B><B>)</B><B>-></B>Color <B>=</B> clBtnFace<B>;</B>
<B>}</B>
<B>}</B>
DWORD dwEnd <B>=</B> GetTickCount<B>(</B><B>)</B><B>;</B>
DWORD dwDiff <B>=</B> dwEnd <B>-</B> dwStart<B>;</B>
Label1<B>-></B>Caption <B>=</B> IntToStr<B>(</B>dwDiff<B>)</B><B>;</B>
<B>}</B>
<FONT color=navy>//-----------------------------------------------------------------</FONT>
<FONT color=navy>// Benchmark for ClassNameIs</FONT>
<B>void</B> <B>__fastcall</B> TForm1<B>:</B><B>:</B>Button2Click<B>(</B>TObject <B>*</B>Sender<B>)</B>
<B>{</B>
<B>int</B> nCount <B>=</B> ComponentCount<B>;</B>
DWORD dwStart <B>=</B> GetTickCount<B>(</B><B>)</B><B>;</B>
<B>for</B> <B>(</B><B>int</B> j<B>=</B><FONT color=blue>0</FONT><B>;</B> j<<FONT color=blue>1000000</FONT><B>;</B> j<B>++</B><B>)</B>
<B>{</B>
<B>for</B> <B>(</B><B>int</B> i<B>=</B><FONT color=blue>0</FONT><B>;</B> i<nCount<B>;</B> i<B>++</B><B>)</B>
<B>{</B>
<B>if</B><B>(</B>Components<B>[</B>i<B>]</B><B>-></B>ClassNameIs<B>(</B><FONT color=blue>"TEdit"</FONT><B>)</B><B>)</B>
<B>(</B><B>(</B>TEdit <B>*</B><B>)</B>Components<B>[</B>i<B>]</B><B>)</B><B>-></B>Color <B>=</B> clBtnFace<B>;</B>
<B>}</B>
<B>}</B>
DWORD dwEnd <B>=</B> GetTickCount<B>(</B><B>)</B><B>;</B>
DWORD dwDiff <B>=</B> dwEnd <B>-</B> dwStart<B>;</B>
Label2<B>-></B>Caption <B>=</B> IntToStr<B>(</B>dwDiff<B>)</B><B>;</B>
<B>}</B>
<FONT color=navy>//-----------------------------------------------------------------</FONT>
<FONT color=navy>// Benchmark for dynamic_cast</FONT>
<B>void</B> <B>__fastcall</B> TForm1<B>:</B><B>:</B>Button3Click<B>(</B>TObject <B>*</B>Sender<B>)</B>
<B>{</B>
<B>int</B> nCount <B>=</B> ComponentCount<B>;</B>
DWORD dwStart <B>=</B> GetTickCount<B>(</B><B>)</B><B>;</B> <B>for</B> <B>(</B><B>int</B> j<B>=</B><FONT color=blue>0</FONT><B>;</B> j<<FONT color=blue>1000000</FONT><B>;</B> j<B>++</B><B>)</B>
<B>{</B>
<B>for</B> <B>(</B><B>int</B> i<B>=</B><FONT color=blue>0</FONT><B>;</B> i<nCount<B>;</B> i<B>++</B><B>)</B>
<B>{</B>
<B>if</B><B>(</B> <B>dynamic_cast</B><TEdit <B>*</B><B>></B><B>(</B>Components<B>[</B>i<B>]</B><B>)</B><B>)</B>
<B>(</B><B>(</B>TEdit <B>*</B><B>)</B>Components<B>[</B>i<B>]</B><B>)</B><B>-></B>Color <B>=</B> clBtnFace<B>;</B>
<B>}</B>
<B>}</B>
DWORD dwEnd <B>=</B> GetTickCount<B>(</B><B>)</B><B>;</B>
DWORD dwDiff <B>=</B> dwEnd <B>-</B> dwStart<B>;</B>
Label3<B>-></B>Caption <B>=</B> IntToStr<B>(</B>dwDiff<B>)</B><B>;</B>
<B>}</B>
<FONT color=navy>//-----------------------------------------------------------------</FONT>
</PRE><BR><IMG align=bottom border=0 src="images/classnameis.gif" width="288" height="206">
<BR>
<H4>Figure 1. The benchmark form after running the test</H4>
<P>Figure 1 reveals that <TT>ClassNameIs</TT> runs about 10 times slower
than <TT>__classid</TT>. <TT>dynamic_cast</TT> is a little slower than
<TT>__classid</TT>, but not by much. The question we have to ask ourselves
is this: was this an accurate benchmark of the three routines? </P>
<P>The answer to that question is no. The benchmark code for
<TT>ClassNameIs</TT> contains a minor flaw. This flaw affects the
performance of the routine, and skews the results of the benchmark. Can
you find the flaw in the benchmark code for <TT>ClassNameIs</TT>?
<H4><A href="wwwtc2answer.htm"
target=_top>Answer</A> </H4></TD></TR></TBODY></TABLE></CENTER></BODY></HTML>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?