Results 1 to 27 of 27

Thread: TimerEx, hi precision timer using QueryPerformanceCounter

Threaded View

  1. #1

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,915

    TimerEx, hi precision timer using QueryPerformanceCounter

    You are (obviously) welcome to read all the posts in this thread. But I've made additional comments in post #26 that may be of interest to you.

    I've posted this class many times in specific question threads, and I'm often referring to it, so I thought I'd post it here. It's just a high precision timer using the QueryPerformanceCounter API call.

    I'm posting the entire CLS code (including the header stuff). So, to use it, open Notepad (or any ASCII editor), past it in, and save as TimerEx.cls. I've also attached in in the attached ZIP.

    As a note, it's got the VB_PredeclaredId flag set to True. That can only be done to a CLS module with Notepad, and can't be done from the VB6 IDE. But, once done, it works perfectly. This flag auto instantiates the CLS module, using the CLS module's name as the object variable name. (Forms have this VB_PredeclaredId flag set to True by default. That's why you can use their names as an object variable that auto instantiates.)

    With this VB_PredeclaredId = True, there's no need to declare any variable. Just start using the TimerEx, and it'll just work. It basically just becomes another keyword in the VB6 language.

    There is only one read-only property (actually a function) named Value. However, it has it's Value.VB_UserMemId set to 0. This means it's the default. So you don't even have to say TimerEx.Value. You can just say TimerEx to get the value.

    As a final note, if you use this for timing tests (which it's very good at), be sure to just get a value from TimerEx before you start your timings. Any CLS declared with New or with its VB_PredeclaredId flag set to True will be instantiated the first time you touch it, and not before. Therefore, you don't want your instantiation time interfering with anything, so "touch" it before using it in a critical way, and then it'll stay instantiated (unless you explicitly set it to Nothing).

    Here's the code (with header info):

    Code:
    
    VERSION 1.0 CLASS
    BEGIN
      MultiUse = -1  'True
      Persistable = 0  'NotPersistable
      DataBindingBehavior = 0  'vbNone
      DataSourceBehavior  = 0  'vbNone
      MTSTransactionMode  = 0  'NotAnMTSObject
    END
    Attribute VB_Name = "TimerEx"
    Attribute VB_GlobalNameSpace = False
    Attribute VB_Creatable = True
    Attribute VB_PredeclaredId = True
    Attribute VB_Exposed = False
    '
    ' This class has VB_PredeclaredId = True.
    ' Also, the Value is set to the default property.
    ' Therefore, TimerEx will just act like a new built-in function.
    ' No need to declare an object variable or explicitly instantiate.
    '
    Option Explicit
    '
    Private Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As Currency) As Long
    Private Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As Currency) As Long
    '
    Private cFreq As Currency
    '
    
    Private Sub Class_Initialize()
        QueryPerformanceFrequency cFreq
    End Sub
    
    Public Function Value() As Double
    Attribute Value.VB_UserMemId = 0
        ' Must be Public (not Friend) so we can set default property.
        ' Returns seconds, a double, with high-precision.
        ' Caller is responsible for keeping track of start/stop times.
        ' Basically, it works exactly like the built-in Timer function, but with much more precision.
        Dim cValue As Currency
        QueryPerformanceCounter cValue
        Value = cValue / cFreq  ' The division will return a double, and it also cancels out the Currency decimal points.
    End Function
    
    

    And, the attachment is below.

    Enjoy,
    Elroy

    EDIT1: Just as a notice, this TimerEx returns the number of seconds elapsed since the system on which it's running was last booted. And, AFAIK, it never rolls over. A Double can easily hold enough seconds that your computer would crumble to dust before it would need to roll over. This is in contrast to the built-in Timer function, which is pegged at midnight, and rolls over each day. Typically, I only use these things for Deltas (differences) so I don't care about their zero basis.
    Attached Files Attached Files
    Last edited by Elroy; Sep 17th, 2019 at 07:55 AM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width