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&lt;<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&lt;nCount<B>;</B> i<B>++</B><B>)</B>

        <B>{</B>

            <B>if</B><B>(</B>Components<B>[</B>i<B>]</B><B>-&gt;</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>-&gt;</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>-&gt;</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&lt;<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&lt;nCount<B>;</B> i<B>++</B><B>)</B>

        <B>{</B>

            <B>if</B><B>(</B>Components<B>[</B>i<B>]</B><B>-&gt;</B>ClassNameIs<B>(</B><FONT color=blue>&quot;TEdit&quot;</FONT><B>)</B><B>)</B>

                <B>(</B><B>(</B>TEdit <B>*</B><B>)</B>Components<B>[</B>i<B>]</B><B>)</B><B>-&gt;</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>-&gt;</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&lt;<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&lt;nCount<B>;</B> i<B>++</B><B>)</B>

        <B>{</B>

            <B>if</B><B>(</B> <B>dynamic_cast</B>&lt;TEdit <B>*</B><B>&gt;</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>-&gt;</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>-&gt;</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 + -
显示快捷键?