Vítejte na blog.vyvojar.cz Přihlásit | Registrovat | Pomoc
Titulní Blogy Fotky Soubory

Petr Lazecký

Chorobovýplody

Petr's Takeaway (8) - Jednoduchá třída pro měření jak dlouho trvá vykonávání kódu

Níže uvedenou třídu jsem používal delší dobu pro jednoduché měření toho jak dlouho trvá vykonávání jisté části kódu. A musím říci že až dodnes jsem měřil špatně. Problém byl v tom že jsem neměřil pouze to co jsem potřeboval ale ještě něco navíc.

Pokud se podíváte na kód třídy tak si určitě všimnete atributu [SuppressUnmanagedCodeSecurity] který je aplikován při deklaraci P\Invoke metod. Bez tohoto atributu se pří každém přechodu z managed do unmanaged provádí procházení zásobníku aby framework ověřil že všichni volající mají oprávnění volat unmanaged kód. Takže naměřený čas obsahoval i toto procházení zásobníku. Attribut [SuppressUnmanagedCodeSecurity] redukuje bezpečnostní kontrolu tím že uprávnění volat unmanaged kód se kontroluje pouze v době linkování (JIT). Takže musíte nechat třídu StopWatch "zahořet" tím že aspoň jednou zavoláte metody Stop() a Start() před vlastním měřením. Tím dojde ke zkompilování těchto metod a pak již můžete měřit trošku přesněji.

using System;
using System.Text;
using System.Security;
using System.Diagnostics;
using System.Runtime.InteropServices;

public class StopWatch
{
    private long m_Start;
    private long m_Finish;
    private long m_Frequency;

    [DllImport("kernel32.dll")]
    [SuppressUnmanagedCodeSecurity]
    extern private static short QueryPerformanceCounter(ref long x);
    
    [DllImport("kernel32.dll")]
    [SuppressUnmanagedCodeSecurity]
    extern private static short QueryPerformanceFrequency(ref long x);
    
    public StopWatch()
    {
        Reset();
    }
    public void Start()
    {
        QueryPerformanceFrequency(ref m_Frequency);
        QueryPerformanceCounter(ref m_Start);
    }
    public void Stop()
    {
        QueryPerformanceCounter(ref m_Finish);
    }
    public void Reset()
    {
        m_Start  = 0;
        m_Finish  = 0;
        m_Frequency = Int32.MaxValue;
    }
    public double Duration
    {
        get
        {
            return (m_Finish - m_Start) * 1.0 / m_Frequency;
        }
    }
}

Zveřejněno Saturday, October 02, 2004 9:09 PM by lazo
Vedeno pod:

Upozornění na nové komentáře

Pokud chčeš dostávat upozornění emailem na změny u toho příspěvku,tak se zaregistruj zde.zde

Odebírat komentáře k tomuto příspěvku pomocí RSS

Komentář

 

Honza napsal:

Nebylo by efektivnejsi pouzit atribut SuppressUnmanagedCodeSecurity pro celou tridu? Treba by tim odpadla nutnost zahorovani pres Start a Stop. Treba jsem ale uplne mimo - s uvedenym atributem jsem se setkal poprve.
October 3, 2004 4:12 PM
 

Petr Lazecky napsal:

To by nepomohlo protoze JITer pracuje na urovni metod nikoliv celych trid. Takze dokud nezavolate metodu dane tridy tak neni jeji X86 assembly verze k dispozici. A pristup ke tride neznamena JIT vsech metod tridy ale pouze tech co je treba.
SuppressUnmanagedCodeSecurity by se mel pouzivat s nejvetsi opatrnosti protoze tim muzete do Vaseho kodu zavlect vazne bezpecnostni chyby. V pripade teto jednoduche tridy to neni az tak videt ale pokud byste aplikoval attribut na celou tridu a v budoucnu by nekdo do Vasi tridy pridal dalsi metody nebo by se rozhodl dedit z nejake bazove tridy tak by se tento atribut aplikoval i na tyto pridane metody. Proto jsem se rozhodl pouzit atribut na urovni jednolivych deklaraci a ne cele tridy. Jde o snahu explicitne vyjadrit ze si preji mit tento atribut pouze u techto dvou deklaraci a nikde jinde.
October 4, 2004 10:25 AM
 

Michalův zápisníček napsal:

.Net 2.0 konečně obsahuje přesné měření času v třídě System.Diagnostics.StopWatch, takže se nemusí volat

July 1, 2007 9:56 PM

Vytvoření nového komentáře

(povinný) 
(nepovinný)
(povinný) 
Opiš čísla, která vidíš na obrázku:
Odeslat
Powered by Community Server (Personal Edition), by Telligent Systems