JohnLM 27 Posted September 22 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
JohnLM 27 Posted September 22 I tried: Uses SysUtils; but get the following message: [dcc32 Error] Unit1.pas(84): E2003 Undeclared identifier: 'GetTickCount64' Share this post Link to post
Pat Foley 56 Posted September 22 gOOGLE speculates Xe7 in System.Classes has TThread.GetTickCount64; Share this post Link to post
JohnLM 27 Posted September 22 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
Vincent Parrett 909 Posted September 22 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
Tom F 87 Posted September 22 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
Stefan Glienke 2190 Posted September 23 Forget about GetTickCount(64) when doing any performance measuring - just use TStopwatch from System.Diagnostics. 4 Share this post Link to post
Kas Ob. 160 Posted September 23 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
JohnLM 27 Posted September 23 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
JohnLM 27 Posted September 23 Thanks @Kas Ob., I saw that post earlier today during my searches and trial/errors. Share this post Link to post
JohnLM 27 Posted September 23 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. So it looks like it is taking 1.8 seconds to process this list of 39960 items. Share this post Link to post
Stefan Glienke 2190 Posted September 23 (edited) Just fyi: counting occurrences of approx 40k 5-character-long strings takes about 1ms with a Spring4d multiset and is a one-liner. Edited September 23 by Stefan Glienke Share this post Link to post
JohnLM 27 Posted September 23 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
Kas Ob. 160 Posted September 23 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
Stefan Glienke 2190 Posted September 23 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
david berneda 72 Posted September 23 8 hours ago, Kas Ob. said: KUSER_BASE_ADDRESS More tech info: https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/ntexapi_x/kuser_shared_data/index.htm Share this post Link to post