Visual C++ 2003
자체 프로파일러 없음, CLR은 현재 1.1 버전 만들고 있음 2005 Team suite버전에 추가될 듯

Devpartner profiler for free 사용
http://www.compuware.com/products/devpartner/profiler/default.asp?cid=701000000004ej0AAA&focus=&productfocus=&source=Web+-+Evaluation+Request&offering=DevPartner&productfamily=DevPartner&desc=The+DevPartner+Community+Profiler+Edition+is+a+product+download+that+offers+customers+and+prospects+a+high-level+view+of+the+performance+profiling+capabilities+of+DevPartner+Studio+Professional+Edition.&trk=200601-74

CLR profiler는 CLR Profiler (v1.1)
http://www.microsoft.com/downloads/details.aspx?FamilyId=86CE6052-D7F4-4AEB-9B7A-94635BEEBDDA&displaylang=en



Visual C++ 6.0
자체 프로파일러 사용

  1.. 메뉴의 Project/Setting...을 열어 Link tab에
  Enable Profiling이라는 체크박스를 체크합니다.


  2.. 프로젝트를 다시 빌드합니다.


  3.. Build 메뉴의 맨끝에 있는 Profile...을 선택합니다.


  4.. 다이얼로그에 보면 Profile Type이 몇가지 나옵니다.
  이중에 Function timing을 선택하고 OK를 누르면 실행됩니다.
  (이때, 실행파일이 있는 폴더에 *.map파일이 반드시 있어야 합니다.)


  5.. 종료후에 Output창 맨끝 tab에 있는 Profile탭을 열면 결과를 볼수
있습니다.


여기까지는 exe파일의 profiling에만 해당되는 사항입니다.
다음은 dll의 profiling방법입니다.


  1.. 위 단계의 3번까지는 dll도 똑같습니다.
  (dll과 exe모두 Enable Profiling상태로 빌드하고, exe가 ActiveProject가
되어있어야 합니다.)


  2.. 일단 아래와 같은 내용의 profdll.bat파일을 만듭니다.

  copy %1.dll save
  prep /OM %1.dll
  copy %1._ll %1.dll
  profile /I %1 /O %1 %2
  copy save %1.dll
  prep /M %1
  plist %1


  3.. command line에서 실행할 경우는 아래와 같이 실행시킵니다. (파일이름은
확장자없이)
  profdll dllfile exefile


  4.. 비주얼스튜디오내에서 실행할 경우에는
  Build/Profile...의 대화상자에서 Profile type중 custom을 선택합니다.
  그리고나서, Custom Settings에서 3번과 같이 써주면 되구요.


마지막으로, 실행을 위해서는 Build메뉴의 Profile...을 선택하면 됩니다.

아래는 profile 결과물 샘플입니다.


     Func          Func+Child          Hit
     Time   %         Time      %     Count   Function
-------------------------------------------------------
4832.446  57.5     4832.446  57.5   104418 CString::operator+=(char)
(mfc42d.dll)
  559.958   6.7      559.958   6.7      524 CDC::DrawTextA(class CString
const &,struct tagRECT *,unsigned int) (mfc42d.dll)
  184.740   2.2      196.883   2.3       38
CYWndViewer::OnUpdatePagenext(class CCmdUI *) (ywndviewer.obj)
  137.745   1.6     5059.470  60.2     1496 CYWndViewer::GetToken(unsigned
char &,class CString &) (ywndviewer.obj)
   88.514   1.1       88.514   1.1     3893 CString::~CString(void)
(mfc42d.dll)


============================================================================
===

Profiler를 이용하면 아래와 같은 재미있는 성능테스트도 할수있습니다.
아래는 '비사모'의 Visual C++ Tip/Tricks 게시판에서 퍼온 글입니다.


PERFORMANCE TESTS
COMPUTER DATA:
Processor: Pentium Pro 200
Memory: 64 MB
Software: Visual C++ 5.0
System: NT 4.0 with service pack 2

CWnd::GetDlgItem() versus ::GetDlgItem()
Using member variables in functions versus automatic variables
Decrease the number of allocations that is done in a application for CString
Using pointers to objects versus many parameters when sending data to
functions

How to improve the speed for a application depends on what type of
application you are building.
Every application usualy have some sort of core where a lot of time is
spent.
Improving speed for this core will make your whole application run faster.
When the design of a new application is started it is vital that you spend a
lot of time to try to figure out
what the applications main tasks will be (programmatically).
And that a core is built that can manage most of these tasks.
If the application don't have some sort of core.
It is either a very strange application or you have "spagetti code".
If you have "spagetti" you are in big trouble.
Lists, drawing code, memory management, database design, SQL-queries etc.
Are areas where you can gain much improvement by designing for speed.
The samples below will not make a big impact for the speed of your
application,
but it is small improvements that you might not have thought about.


Back to home

CWnd::GetDlgItem() versus ::GetDlgItem()
  When getting pointers to a controls in MFC, CWnd::GetDlgItem() is often
used.
  There is a lot of improvement to do if you are getting pointers or a
handle to different controls
  in your application by using the API ::GetDlgItem() instead of
CWnd::GetDlgItem().
  This is because MFC are storing objects for each window in a hash table
and are using the handle as a key.
  So when the CWnd::GetDlgItem() is used,
  the ::GetDlgItem() gets the handle and then then the window object is
looked up in hash table.
  If the window object is found (serious error if not !) it is returned.

----------------------------------------------------------------------------
----

void CTestDlg::GetDlgItemAPI()
{
   HWND hEdit; UINT uCounter;
   for( uCounter = 0; uCounter < 100000; uCounter++ )
   {
      hEdit = ::GetDlgItem( m_hWnd, IDC_EDIT1001 );
   }
}

void CTestDlg::GetDlgItemMFC()
{
   CEdit* pEdit; UINT uCounter;
   for( uCounter = 0; uCounter < 100000; uCounter++ )
   {
      pEdit = (CEdit*)GetDlgItem( IDC_EDIT1001 );
   }
}

void CTestDlg::OnButton1()
{
   GetDlgItemMFC();
   GetDlgItemAPI();
}

     Func       Func+Child     Hit
     Time          Time       Count     Function
---------------------------------------------------------
267.004         267.004         1    CTestDlg::GetDlgItemMFC(void)
38.205          38.205         1    CTestDlg::GetDlgItemAPI(void)


Using member variables in functions versus automatic variables
  When you are using member variables in member functions.
  There is some overhead that is done.
  The "this" pointer is loaded into one of the CPU's register before the
member is used.
  The bad thing about this is that the code gets bigger and a little slower.
  If you are using a member variable in a member function on many places or
like the sample below, in a loop.
  Then you can increase the speed and decrease the code size by assigning
automatic variables to member variables.
  Use these automatic variables in the function
  and when the function is finished assign the members to the automatic
variables.

----------------------------------------------------------------------------
----

void CTestDlg::Member()
{
   UINT uCounter;
   m_lSum = 0; m_lTemp = 0;

   for( uCounter = 0; uCounter < 1000000; uCounter++ )
   {
      m_lTemp++;
      m_lTemp++;
      m_lSum += m_lTemp;

      if( m_lSum )  m_lSum--;
   }
}

void CTestDlg::Auto()
{
   UINT uCounter; LONG lSum, lTemp;
   lSum = 0; lTemp = 0;

   for( uCounter = 0; uCounter < 1000000; uCounter++ )
   {
      lTemp++;
      lTemp++;
      lSum += m_lTemp;

      if( lSum )  lSum--;
   }

   m_lTemp = lTemp; lSum = m_lSum;
}

void CTestDlg::OnButton1()
{
   Auto();
   Member();
}

  Func      Func+Child        Hit
  Time         Time          Count  Function
---------------------------------------------------------
36.801          36.801         1    CTestDlg::Member(void)
15.071          15.071         1    CTestDlg::Auto(void)





Decrease the number of allocations that is done in a application for CString
  CString is very fast if used correctly. But you need to how it works
internally.
  When you add text to a CString and the internal buffer is to small,
  it needs to increase the buffer and copy the new text into it.
  If the buffer is large enough to fit the characters that is added, no
allocation is done.

----------------------------------------------------------------------------
----

void CTestDlg::NoPreAlloc()
{
   CString stringText;

   stringText += _T("1");
   stringText += _T("2");
   stringText += _T("3");
   stringText += _T("4");
   stringText += _T("5");
   stringText += _T("6");
   stringText += _T("7");
   stringText += _T("8");
   stringText += _T("9");
}

void CTestDlg::PreAlloc()
{
   CString stringText;

   stringText.GetBuffer( 10 );
   stringText += _T("1");
   stringText += _T("2");
   stringText += _T("3");
   stringText += _T("4");
   stringText += _T("5");
   stringText += _T("6");
   stringText += _T("7");
   stringText += _T("8");
   stringText += _T("9");
}

void CTestDlg::OnButton1()
{
   UINT uCounter;

   for( uCounter = 0; uCounter < 1000; uCounter++ )
   {
      NoPreAlloc();
      PreAlloc();
   }
}

  Func  Func+Child    Hit
  Time     Time      Count  Function
------------------------------------
31.739     31.739    1000 CTestDlg::NoPreAlloc(void)
10.370     10.370    1000 CTestDlg::PreAlloc(void)





Using pointers to objects versus many parameters when sending data to
functions
  It is best to use a pointer to an object instead of sending many
parameters.
  The gain in performance for many parameters is very small and as you can
se in the sample below,
  it is only acquired in very extreme cases.
  Most often you don't need to assign all members for the object before
calling the function.
  It is easier to modify the code if pointer to an object is sent, instead
of using a lot of parameters.
There is some places where it could be better to send many parameters
instead of pointer to an object,
one is when a object is using it's own private member functions.

----------------------------------------------------------------------------
----

struct SSDummy {int i1;int i2;int i3;int i4;int i5;int i6;int i7;};

void CTestDlg::ManyParameter( int i1,int i2,int i3,int i4,int i5,int i6,int
i7 )
{
   int iSum;
   iSum = i1 + i2 + i3 + i4 + i5 + i6 + i7;
}

void CTestDlg::OneParameter( SSDummy* pDummy )
{
   int iSum;
   iSum = pDummy->i1 + pDummy->i2 + pDummy->i3 +
          pDummy->i4 + pDummy->i5 + pDummy->i6 + pDummy->i7;
}

void CTestDlg::Many()
{
   int i1; int i2; int i3; int i4; int i5; int i6; int i7;
   i1 = 0; i2 = 0; i3 = 0; i4 = 0; i5 = 0; i6 = 0; i7 = 0;

   ManyParameter( i1, i2, i3, i4, i5, i6, i7 );
}

void CTestDlg::One()
{
   SSDummy Dummy;
   Dummy.i1 = 0; Dummy.i2 = 0; Dummy.i3 = 0; Dummy.i4 = 0;
   Dummy.i5 = 0; Dummy.i6 = 0; Dummy.i7 = 0;
   OneParameter( &Dummy );
}

void CTestDlg::OnButton1()
{
   UINT uCounter;

   for( uCounter = 0; uCounter < 100000; uCounter++ )
   {
      Many();
      One();
   }
}

  Func Func+Child    Hit
  Time    Time      Count  Function
------------------------------------
30.230    37.922   100000  CTestDlg::One(void)
19.668    24.565   100000  CTestDlg::Many(void)
7.693     7.693   100000  CTestDlg::OneParameter(struct SSDummy *)
4.897     4.897   100000
CTestDlg::ManyParameter(int,int,int,int,int,int,int)

'KB > C/C++' 카테고리의 다른 글

cl.exe Episode XIII: Attack of the Standards: VC6, 7에서 C++ 표준 적용 사항  (0) 2006.06.28
typeof  (0) 2006.06.28
함수 링크 순서 정해주기  (0) 2005.10.28
RSA를 이해하기 위한 코드  (0) 2005.03.25
[펌] vc 5, 6 stl 버그 픽스  (0) 2004.09.10

+ Recent posts