Jump to content

FredS

Members
  • Content Count

    408
  • Joined

  • Last visited

  • Days Won

    4

Posts posted by FredS


  1. 19 minutes ago, John Kouraklis said:

    'abc and abc.def'

     

    The code below will return: 'yes, yes.def'

    v := TRegEx.Replace('abc, abc.def', '\babc\b', 'yes', [TRegExOption.roIgnoreCase]);
    \babc\b
    
    Options: Case insensitive; Exact spacing; Dot doesn’t match line breaks; ^$ match at line breaks; Numbered capture; Skip zero-length matches
    
    Assert position at a word boundary (position preceded or followed—but not both—by an ASCII letter, digit, or underscore) «\b»
    Match the character string “abc” literally (case insensitive) «abc»
    Assert position at a word boundary (position preceded or followed—but not both—by an ASCII letter, digit, or underscore) «\b»
    
    Created with RegexBuddy

     


  2. 1 hour ago, Mike Torrettinni said:

    I don't really have the typical need for them

     

    Fine for Global vars as long as you don't need to finalize. At that point just change to a class.
    Pretty sure you don't actually want Global Instance data.. more like a snack without the preparation and cleanup 🙂

     

    //MMWIN:CLASSCOPY
    unit _MM_Copy_Buffer_;
    
    interface
    
    type
      TGlobal = record
        class var
          Id      : Integer;
          RecName : string;
          Values  : TArray<TValue>;
          class constructor Create;
      private
          class function GetNewProperty: Integer; static;
          class procedure SetNewProperty(const Value: Integer); static;
      public
          class property NewProperty: Integer read GetNewProperty write SetNewProperty;
      end;
    
    
    implementation
    
    class constructor TGlobal.Create;
    begin
      inherited;
      // TODO -cMM: TGlobal.Create default body inserted
    end;
    
    class function TGlobal.GetNewProperty: Integer;
    begin
      // TODO -cMM: TGlobal.GetNewProperty default body inserted
      Result := ;
    end;
    
    class procedure TGlobal.SetNewProperty(const Value: Integer);
    begin
      // TODO -cMM: TGlobal.SetNewProperty default body inserted
    end;
    
    end.

     

    • Thanks 1

  3. Some very old versions of Delphi had this issue, simple fix was to use:

     

    function MyFileExits(FileName: string): boolean;
    var
      SearchRec: TSearchRec;
    begin
      if (FindFirst(FileName, faAnyFile, SearchRec) = 0) then
      begin
        SysUtils.FindClose(SearchRec);
        Result := True;
      end
      else
        Result := False;
    end;

     


  4. On 1/2/2019 at 7:45 PM, pyscripter said:

    in Rio it seems to work OK

     

    Modified your code to get a better look at the difference.

     

    Both Executed in Berlin 10.1.2
    Ideally #1 should reach a higher WorkerThreadCount during its two minutes of execution but still the same with Rio.

    #3 may be an issue (also in Rio), imagine running a pile of low intensity tasks first then executing something that loads Data Modules, Databases and whatnot.. starting at the same count you left off could cause out of memory issues unless dealt with (not tested).

    #4 IMO is handled better in Berlin, the AverageCPUUsage delegates the Pool to drop below MinLimitWorkerThreadCount.

     

    ** RIO System.Threading unit, modified to compile in Berlin

      #1 Slow increase, never reached full ActiveTask Count
        00:02:13.8790372
        AverageCPUUsage: 35
        WorkerThreadCount: 34
        MinLimitWorkerThreadCount: 4

      #2 Increased to 58 immediately, holds appropriate AverageCPUUsage    
        00:01:11.9777749
        AverageCPUUsage: 90
        WorkerThreadCount: 58
        MinLimitWorkerThreadCount: 50

      #3 Starts off with #2 WorkerThreadCount and holds appropriate AverageCPUUsage     
        00:01:11.8997475
        AverageCPUUsage: 89
        WorkerThreadCount: 58
        MinLimitWorkerThreadCount: 4

      #4 Does NOT hold appropriate AverageCPUUsage    
        00:01:35.0015869
        AverageCPUUsage: 100
        WorkerThreadCount: 99
        MinLimitWorkerThreadCount: 99

     

    ** Berlin System.Threading unit, modified with RSP fixes only

     

      #1 Slow increase, never reached full ActiveTask Count
        00:02:13.9110588
        AverageCPUUsage: 34
        WorkerThreadCount: 34
        MinLimitWorkerThreadCount: 4

      #2 Increased to 58 immediately, holds appropriate AverageCPUUsage
        00:01:11.4247095
        AverageCPUUsage: 89
        WorkerThreadCount: 59
        MinLimitWorkerThreadCount: 50
        
      #3 Starts off with #2 WorkerThreadCount and holds appropriate AverageCPUUsage
        00:01:11.6894449
        AverageCPUUsage: 88
        WorkerThreadCount: 59
        MinLimitWorkerThreadCount: 4
     
      #4 Drops appropriately below MinLimitWorkerThreadCount to keep AverageCPUUsage
        00:01:21.0234632
        AverageCPUUsage: 88
        WorkerThreadCount: 78
        MinLimitWorkerThreadCount: 99

     

    program Project2;
    {$APPTYPE CONSOLE}
    uses
      WinApi.Windows,
      System.SysUtils,
      System.Diagnostics,
      System.Threading,
      System.Classes,
      System.TimeSpan;
    
    var
      SW : TStopWatch;
      ActiveTasksTicks : Int64;
    
    const
        SleepMs     = 100;
        SleepCycles = 333;
        HighPrime   = 100 * 1000;
    
    function IsPrime(const Value: Integer): Boolean;
    {$REGION 'History'}
    //  18-Jul-2018 - From a Parallel Task example
    {$ENDREGION}
    var Test, k: Integer;
    begin
      if Value <= 3 then IsPrime := Value > 1
      else if ((Value mod 2) = 0) or ((Value mod 3) = 0) then IsPrime := False
      else begin
        IsPrime := True;
        k := Trunc(Sqrt(Value));
        Test := 5;
        while Test <= k do begin
          if ((Value mod Test) = 0) or ((Value mod (Test + 2)) = 0) then begin
            IsPrime := False;
            break; { jump out of the for loop }
          end;
          Test := Test + 6;
        end;
      end;
    end;
    
    procedure TestParallel;
    var
      TaskArray:  array [1..100] of ITask;
      Ticks : Int64;
      i : integer;
    begin
      for I := Low(TaskArray) to High(TaskArray) do
        TaskArray[I] := TTask.Create(procedure
        var
          s, p: integer;
          Succeeded : Boolean;
          {* GetActiveTasks *}
          function GetActiveTasks: integer;
          var i : integer;
          begin
            Result := 0;
            for i := Low(TaskArray) to High(TaskArray) do
               if (TaskArray[i].Status = System.Threading.TTaskStatus.Running) then begin
                 Inc(Result);
               end;
            end;
        begin
          for s := 1 to SleepCycles do begin
             Ticks := ActiveTasksTicks;
             if (Ticks + TTimeSpan.TicksPerSecond) < SW.ElapsedTicks then begin
               System.AtomicCmpExchange(ActiveTasksTicks, SW.ElapsedTicks, Ticks, Succeeded);
               if Succeeded then begin
                 Write(#13 + Format('ActiveTasks: %3.d,  CPU: %3.d%%', [GetActiveTasks, TThreadPoolStats.Current.CurrentCPUUsage]));
               end;
             end;
             Sleep(SleepMs);
             for p := 1 to HighPrime do isPrime(p);
          end
        end).Start;
      TTask.WaitForAll(TaskArray);
    end;
    
    procedure TestTasks(AMinWorkerThreads : integer);
    var
      TPS : TThreadPoolStats;
    begin
      ActiveTasksTicks := 0;
      SW := TStopWatch.StartNew;
      TThreadPool.Default.SetMinWorkerThreads(AMinWorkerThreads);
      TestParallel;
      Write(#13 + StringOfChar(' ', 72));
      WriteLn(#13 + SW.Elapsed.ToString);
      TPS := TThreadPoolStats.Default;
      WriteLn('AverageCPUUsage: ', TPS.AverageCPUUsage);
      WriteLn('WorkerThreadCount: ', TPS.WorkerThreadCount);
      WriteLn('MinLimitWorkerThreadCount: ', TPS.MinLimitWorkerThreadCount);
      WriteLn;
    end;
    
    begin
      TestTasks(TThread.ProcessorCount);
      TestTasks(50);
      TestTasks(TThread.ProcessorCount);
      TestTasks(99);
      ReadLn;
    end.

     


  5. 44 minutes ago, DelphiMT said:

    Most of these issues were reported during the beta phase

     

    Same as before..

     

    I see a bunch of bugs that occur on every first release of a new version, so no way is any of that run through any kind of testing.

     

    • Throughout the year bugs reported outstrip bugs solved by anywhere from 5-8:1
    • As was explained by another poster, we don't know the actual bugs on the internal system. Yet have become Alpha testers for new releases. Obediently posting bugs that where posted before because of internal testing failure.
    • With the CE edition new releases are quickly evaluated and bugs are reported, my bet is that by the 30 day mark we will be close to equal on this chart: 30 Day Summary
    • The thing is, there are some brilliant Delphi users, and when your read some of those Quality Central reports they come with ways to reproduce and in some cases needed code changes.. yet aren't implemented, sometimes for years..

    Draw your own conclusion, your mileage may vary..

     


  6. 13 minutes ago, Uwe Raabe said:

    It is more a mixture of convenience and shortsightedness.

     

    Normally I just leave things as they are because pushing a string gets really boring.
     

    But in this case I'd like to clear a couple of things up, perhaps I'm not grasping the 'whole'..

    • Other than a few milliseconds lost by the compiler, is there any penalty in the final code?
      Because I can't time it, I have spent a bit of effort on that and I see no issues.
    • If that is the case then this whole cyclical issue falls right along with using 'with' doesn't it ?
      I mean try and get a DX based project out the door without using 'with'..
    • We can't really have interface cyclical units because the compiler barks, yet we can't have implementation cyclical units because of CodeInsight?
      What came first cyclical re-engineering cult or CodeInsight not working?

     

×