Jump to content
JohnLM

Where is GetTickCount64 in Delphi XE7

Recommended Posts

Specs:  Win7, XE7, VCL

 

I was wanting to add a stopwatch to test the speed of a routine I wrote.   It is pretty slow and I guess, badly written, but its my first time ever writing (from scratch) an number-of-occurrence function. 

 

Anyway.  In one of my notes (I keep a history of code snippets) I had a stopwatch() routine some long time ago.  But the routine appears to be missing some code I probably forgot to add.   And in one part of my notes, I wrote down for the Uses clause: System.Diagnostics;?  And when I attempt to compile the routine, it fails.   There is no GetTickCount64 in XE7 I guess. 

 

So, I went to the online companion (https://www.embarcadero.com/RADAICompanion) to see what it could do for me and asked, "Where is GetTickCount64 in Delphi XE7?"

 

And the returned response was: 

 

where is GetTickCount64?
  Unfortunately, I have no knowledge on this subject.

Where is GetTickCount64 in Delphi XE7?
   Provide Feedback
Unfortunately, I have no knowledge on this subject.

 

Does anyone here know where it might be and how to get it working in XE7?

Share this post


Link to post

I tried:  Uses SysUtils; but get the following message: 

 

[dcc32 Error] Unit1.pas(84): E2003 Undeclared identifier: 'GetTickCount64'

Share this post


Link to post

gOOGLE speculates Xe7 in System.Classes has TThread.GetTickCount64

Share this post


Link to post

I believe I have found the answer, but not the unit where it is located.   It has be added like this: 

 


type
  TForm1 = class(TForm)
    btn1: TButton;
    m1: TMemo;
    procedure btn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  function GetTickCount64: uint64{QWord}; stdcall; external kernel32 name 'GetTickCount64'; // <--- added like this.

var
  Form1: TForm1;

...

I will test shortly. 

 

Share this post


Link to post

It was added to the WinApi.Windows unit in 10.4, and as a class function to TThread in 11.0 - the latter abstracts for the different platforms. 

Share this post


Link to post

Hint: When looking for a declaration like you were, do a grep for what you're looking for in the foldesr that contains the source for the Emb units.

On my machine, they're here: C:\Program Files (x86)\Embarcadero\Studio\23.0\source\vcl 

 

Share this post


Link to post

Forget about GetTickCount(64) when doing any performance measuring - just use TStopwatch from System.Diagnostics.

  • Like 4

Share this post


Link to post
9 hours ago, JohnLM said:

Does anyone here know where it might be and how to get it working in XE7?

As mentioned above you can declare it, there is also my emulated version for very old Windows, which is the exact implementation on Windows that do provide GetTickCount64

function GetTickCount64Emu: UInt64;  // can be renamed to GetTickCount64
const
  KUSER_BASE_ADDRESS = $7FFE0000;
begin
  Result := (PUInt64(KUSER_BASE_ADDRESS + $320)^ * PCardinal(KUSER_BASE_ADDRESS + $4)^) shr 24;
end;

from 

 

Share this post


Link to post

I could not figure out how to calculate the elapsed time for the values from GetTickCount64.  I could only get the seconds by using (ET div 1000).  I want at least seconds/msecs output.

 

So I found some old code from one of my old projects that was using TStopWatch and that seems to be working acceptably well in this project.  But once I figure out how to calculate what I need for gettickcount64, I will test both to see if they both report the same values or not, now that I am curious. 

 

I am running the values inside a tmemo along with the calculated number of occurrences list. 

 

I will post the code snippet in my follow-up post below, once I pull it out and incorporate it there for reference and/or critique.  Fwiw, my programming skills are very limited. 

Share this post


Link to post

Thanks @Kas Ob., I saw that post earlier today during my searches and trial/errors. 

Share this post


Link to post

Here is the code snippet I used in this project.   

 

I copy/pasted into the first memo 39960 string values from an excel file.

The 2nd memo holds the output of the number of occurrences and the completion times, as best I could get them working in this project. 

 

uses
  system.Diagnostics; 

.
.

var
  Form1: TForm1;

  starttime: tdatetime;
  finishtime: tdatetime;
  ElapsedTime, totaltime: tdatetime;
  sw: TStopwatch;
    swInfo: record
    swtime: string;
    hour  : integer;
    min   : integer;
    sec   : integer;
    msec  : integer;
  end;


procedure TForm1.btn3Click(Sender: TObject); // this was a test button of several, so btn1, btn2, ... btn3, ... 
var
  Hour, Min, Sec, MSec: word;
begin
  sw.Reset;
  sw := TStopwatch.StartNew;  // Start measuring time

  // the number-of-occurrences processing code in-between these two sections. 

  eT := GetTickCount64 - eT;
  m2.Lines.Add(eT.ToString + ' Msecs');
  et:=et div 1000;
  m2.Lines.Add(eT.ToString + ' Msecs2');
  ElapsedTime := Time - StartTime + Totaltime ;
  DecodeTime(elapsedtime, Hour, Min, Sec, MSec);
  m2.lines.Add(IntToStr(Hour)  + ':'+ IntToStr(Min) + ':'+ IntToStr(Sec) + ':' + IntToStr(Msec));
  m2.Lines.Add(FormatDateTime('hh:nn:ss:zzz',sw.ElapsedMilliseconds/MSecsPerDay));
end; 

** m2 is a tmemo. I regularly use m1/tmemo1 and m2/temo2 a lot in my mini input/output reports. 

 

687994040_im-forumpraxispost-numberofoccurrences.png.e945e7d85165319865a9c7133f5a0b79.png

 

So it looks like it is taking 1.8 seconds to process this list of 39960 items. 

 

Share this post


Link to post

Just fyi: counting occurrences of approx 40k 5-character-long strings takes about 1ms with a Spring4d multiset and is a one-liner.

Edited by Stefan Glienke

Share this post


Link to post

I knew there were faster versions.  I had no doubt that members here can build something quick and far faster than my (snail's speed) version.  

 

My occurrences function took me over two weeks to reach this stage of success.  I knew it was going to be very slow for large lists.  I wrote it from scratch with no libraries and no guides, and no Google assist.  I strictly wanted it to be educational and my own.   I agonised over this the whole time.  When I first started this endeavor, the first thing that popped into my mind was Pointers and bump values, but I lack the knowledge and understanding of them.  I did try and study it at first, but it was too much for me to grasp and I wanted to do this as quickly as I could, so I withdrew the Pointer idea and went the non-advanced route.  I was considering posting up the code here, from proof of concept and all, but thought I would get beaten up on the methods I used, among other things.   Anyway.  It works.  Now all I need to do is fine-tune it, or make another attempt from scratch.  

 

Share this post


Link to post
25 minutes ago, JohnLM said:

I knew there were faster versions.  I had no doubt that members here can build something quick and far faster than my (snail's speed) version.  

 

My occurrences function took me over two weeks to reach this stage of success.  I knew it was going to be very slow for large lists.  I wrote it from scratch with no libraries and no guides, and no Google assist.  I strictly wanted it to be educational and my own.   I agonised over this the whole time.  When I first started this endeavor, the first thing that popped into my mind was Pointers and bump values, but I lack the knowledge and understanding of them.  I did try and study it at first, but it was too much for me to grasp and I wanted to do this as quickly as I could, so I withdrew the Pointer idea and went the non-advanced route.  I was considering posting up the code here, from proof of concept and all, but thought I would get beaten up on the methods I used, among other things.   Anyway.  It works.  Now all I need to do is fine-tune it, or make another attempt from scratch.  

 

Keep learning and trying, fail then fail again until succeeding, that is natural and healthy, we all do learn form our mistaken or inefficient roads and approaches.

 

As for beating, the last time i checked, i am pretty sure no one is did have beating her in the forum, as we all more lazy for that, so it will be shot at or burnt at pyre, so don't be afraid form any question no matter how does look (or sound).

 

Good luck and i am going to continue collecting wood for the pyre, next pyre will be magnificent with bluish green flame (i am still mastering the recipe).

Share this post


Link to post
27 minutes ago, JohnLM said:

I strictly wanted it to be educational and my own.

I figured as much - I just mentioned this because if you look into how it is done, you will find one of two typical implementations of how you can count occurrences:

One being similar to how you would do it in real life: once you find the first occurrence, you add it to your notepad, and after that, you just increase its counter - typically this is being done with a hashtable

The second one is sorting the input because then you don't need to maintain a hashtable for count lookup, but you know that all occurrences are adjacent to each other.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×