Jump to content

pmcgee

Members
  • Content Count

    70
  • Joined

  • Last visited

  • Days Won

    2

Everything posted by pmcgee

  1. pmcgee

    Removing String

    The regex solution above has an issue with nested parentheses ... but could be repeated.
  2. pmcgee

    Pos, SplitString

    Result := MyStr.Split( ['<'] ) [0];
  3. pmcgee

    Detect stack full for recursive routine

    @david_navigator no-one mentioned that a) if you can arrange for calculation by tail-calls, Delphi can eliminate runaway stack increases. b) there are techniques to linearise some recursive functions by decomposing the single function into multiple functions with extra state. c) it may be possible to memoise calculations that might be repeated.
  4. Fibers under the magnifying glass Gor Nishanov (gorn@microsoft.com) - author? of c++ coroutines (Advocating coroutines over fibers.) Abstract "Fibers (sometimes called stackful coroutines or user mode cooperatively scheduled threads) and stackless coroutines (compiler synthesized state machines) represent two distinct programming facilities with vast performance and functionality differences. This paper highlights efficiency, scalability and usability problems of fibers and reaches the conclusion that they are not an appropriate solution for writing scalable concurrent software." https://open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1364r0.pdf
  5. @de la Mancha did you sort this out satisfactorily ?
  6. Neater and equally fast ... type Conts = (edit, button, check, form, frame, listbox, pgctrl, tabctrl, radiobtn, combobox); Ctest = set of Conts; const Strs : array[Conts] of string = ( 'Edit', 'Button', 'Check', 'Form', 'Frame', 'ListBox', 'PageControl', 'TabControl', 'RadioBtn', 'ComboBox' ); function IsIN(aID: Conts): boolean ; // inline; begin const test : Ctest = [button, form, listbox, tabctrl, combobox]; IsIn := aId in test; end;
  7. As Stefan said ... without const ... procedure AssignControlsRec; begin xControlsRec.EditID := 1; xControlsRec.EditStr := 'Edit' ; xControlsRec.ButtonID := 2; xControlsRec.ButtonStr := 'Button' ; xControlsRec.CheckID := 4; xControlsRec.CheckStr := 'Check' ; xControlsRec.FormID := 8; xControlsRec.FormStr := 'Form' ; xControlsRec.FrameID := 16; xControlsRec.FrameStr := 'Frame' ; xControlsRec.ListBoxID := 32; xControlsRec.ListBoxStr := 'ListBox' ; xControlsRec.PageControlID := 64; xControlsRec.PageControlStr := 'PageControl'; xControlsRec.TabControlID := 128; xControlsRec.TabControlStr := 'TabControl' ; xControlsRec.RadioBtnID := 256; xControlsRec.RadioBtnStr := 'RadioBtn' ; xControlsRec.ComboBoxID := 512; xControlsRec.ComboBoxStr := 'ComboBox' ; end; function IsIN(aID: integer): boolean ; // inline; begin const test = xControlsRec.ButtonID + xControlsRec.FormID + xControlsRec.ListBoxID + xControlsRec.TabControlID + xControlsRec.ComboBoxID; IsIn := (test and aID) <> 0; end;
  8. Just wondering if anyone knows a ballpark figure for the "size" of (any of) the Delphi compilers?
  9. To be fair, there's a Catch-22 in that idea. ie don't implement Generics until you have experience implementing Generics. (and the same would apply for trying to use a c++ like move feature) If someone publishes open source ... not part of a (reasonably big) commercial product like RAD ... and it is useful to maybe 80% of people, then sure it's valuable to point out edge cases - but it doesn't mean it should be discouraged. We need *more* Delphi out there. And more understanding of these elements that weren't even part of Delphi in say 2005.
  10. A bit of a challenge ... to produce Delphi code equaling the performance of C++'s next_permutation. Hopefully more readable in Delphi ... unit D_Next_perm_string; interface procedure swapCh(var a:Ansichar; var b:Ansichar); procedure reverse(var s:AnsiString; const a,x:word); function D_next_permutation(var s:AnsiString; const first, end_:word) : boolean; implementation //uses System.Diagnostics; procedure swapCh( var a : Ansichar; var b : Ansichar ); inline; var c : Ansichar; begin if a<>b then begin c := a; a := b; b := c; end; end; procedure reverse(var s:AnsiString; const a,x:word); inline; var i,j : word; //t : string; begin // x is one past the end of string if a = x-1 then exit; j := ( x-a ) shr 1; //trunc((x-a)/2); for i := 1 to j do swapCh( s[a-1+i] , s[x-i] ); end; function D_next_permutation(var s : AnsiString; const first, end_ : word) : boolean; inline; var i, ii, j : word; begin if first = end_ then begin result := false; exit; end; i := first + 1; if i = end_ then begin result := false; exit; end; i := end_ - 1; while true do begin ii := i; dec(i); if s[i] < s[ii] then begin j := end_; repeat dec(j); until s[i] < s[j]; swapCh( s[i] , s[j] ); reverse(s, ii, end_); result := true; exit; end; if i = first then begin reverse(s, first, end_); result := false; exit; end; end; end; end. Ballpark, we're looking at about 6s vs 2s for s = "abcdefghijkl" (12 bytes). Increases by about a factor of 10 per character beyond that. Note the c++ end() iterator is **one past the end of string**, so ... D_next_permutation(s,1,13)
  11. Sure ... byte / ansichar is a simple case ... but you need to start with simple and solve it the best you can before tackling a bigger / harder problem. The testing is made faster by just using a shorter string. The increase in time is about x10 at the 12 mark ... so 11 is quicker, and 10 is almost immediate.
  12. I'm a little confused. First post *is* the Delphi code. I've been learning about C++ for a couple years, alongside 20 with Delphi, and the ideas from both are interesting to me. Naively, it seems like a Delphi version should be able to produce about the same performance. Teasing that out should be educational.
  13. The calling code from c++ : int main() { const std::string Test = "abcdefghijkl"; int i = 0; std::string v = Test; Timer timer; timer.start(); do { ++i; } while ( std::next_permutation( v.begin(), v.end() ) ); timer.stop(); std::cout << "C++ " << i << "\n"; std::cout << "Seconds: " << timer.elapsedSeconds() << std::endl; AnsiString s = Test.c_str(); int len = s.Length()+1; i = 0; Timer timer2; timer2.start(); do { ++i; } while ( D_next_permutation(s, 1, len ) ); timer2.stop(); std::cout << "Delphi " << i << "\n"; std::cout << "Seconds: " << timer2.elapsedSeconds() << std::endl; getchar(); return 0;
  14. @Kas Ob. posted this in the original thread : procedure reverse2(var s: AnsiString; const a, x: word); inline; var i, j: word; tmpChar: Byte; SBytes: pByte absolute s; begin if a = x - 1 then exit; j := (x - a) shr 1; // trunc((x-a)/2); for i := 1 to j do begin tmpChar := SBytes[a - 1 + i]; SBytes[a - 1 + i] := SBytes[x - i]; SBytes[x - i] := tmpChar; end; end; var st: AnsiString; i: Integer; D: Uint64; begin st := '1234567890ab'; Writeln(st); d := GetTickCount; for i := 1 to 479001600 do // 12! reverse(st, 1, 12); D := GetTickCount - D; Writeln(d); st := '1234567890ab'; Writeln(st); d := GetTickCount; for i := 1 to 479001600 do reverse2(st, 1, 12); D := GetTickCount - D; Writeln(d); Readln; end. With these results ... (32 bit? 64 bit? compile) 1234567890ab 14125 1234567890ab 4891
  15. I didn't recall correctly. This was a significant speed up : procedure swapByte( a:Pbyte ; b:Pbyte ); inline; begin if a <> b then begin a^ := a^ + b^; b^ := a^ - b^; a^ := a^ - b^ ; end; end; swapByte( @s[a-1+i] , @s[x_-i] );
  16. Maybe this is OT for this thread. I'll look up where to start a new one, and add a link.
  17. I had tried a couple things there ... this was a small improvement. I haven't pulled apart the assembly code yet. It's just an ongoing interest. It'll be fun to try it with char/byte array. procedure swapByte( a:Pbyte ; b:Pbyte ); inline; begin if a <> b then begin a^ := a^ + b^; b^ := a^ - b^; a^ := a^ - b^ ; end; end; procedure swapChar( var a : Ansichar; var b : Ansichar ); inline; var c : Ansichar; begin if a<>b then begin c := a; a := b; b := c; end; end;
  18. Just checking ... You can characterise one edge by one TPoint? or one edge by 4 TPoints? or does Fedges describe a parallelogram? Is ok. "GEORect". I get it. (I'm not sure 'edges' is the best name) ... (also ... can't see how to delete posts.)
  19. I came across this trying to duplicate C++'s std::next_permutation using Delphi. I went through various modifications, and had left a string declaration in where it was no longer needed: procedure reverse(var s:AnsiString; const a,x:word); inline; var i,j : word; //t : string; begin // x is one past the end of string if a = x-1 then exit; j := ( x-a ) shr 1; // trunc((x-a)/2); for i := 1 to j do swapCh( s[a-1+i] , s[x-i] ); end; All permutations of 12 chars = 479,001,600. C++ = 2s. Commenting out the string reduced the Delphi code from 9s to 6s. (I haven't been back to it since then.)
×