Jump to content

pyscripter

Members
  • Content Count

    1020
  • Joined

  • Last visited

  • Days Won

    66

Everything posted by pyscripter

  1. I was trying to improve the performance of SynEdit in handling files with super long lines (e.g. 50K characters). In doing so I came across an unexpected optimization that had a spectacular impact on performance. See this innocent looking function probably written two decades ago (fCasedLine is a PChar): function TSynCustomHighlighter.GetToken: string; var Len: Integer; begin Len := Run - fTokenPos; SetLength(Result, Len); if Len > 0 then StrLCopy(@Result[1], fCasedLine + fTokenPos, Len); end; By measuring I found that this function (called zillions of times) was a bottleneck and replaced it with: function TSynCustomHighlighter.GetToken: string; var Len: Integer; begin Len := Run - fTokenPos; SetString(Result, fCasedLine + fTokenPos, Len); end; The impact was massive. Both SetString and StrLCopy in x64 are implemented in pascal (not assembly) using Move. So initially I was puzzled. However here is the reason. Look at StrLCopy: function StrLCopy(Dest: PWideChar; const Source: PWideChar; MaxLen: Cardinal): PWideChar; var Len: Cardinal; begin Result := Dest; Len := StrLen(Source); if Len > MaxLen then Len := MaxLen; Move(Source^, Dest^, Len * SizeOf(WideChar)); Dest[Len] := #0; end; Can you see the problem? It is the call to StrLen(Source)! In my case the Source was very very long strings, the length of which was unnecessarily calculated the hard way. The lesson here is that you need to identify the bottlenecks by measuring. You may be in for surprises, sometimes pleasant ones,
  2. pyscripter

    String optimization

    TStopwatch and occasionally VTune.
  3. I think var SList := Shared<TMyStringList>.Make(TMyStringList.Create(dupIgnore, True, False)); should work.
  4. pyscripter

    python delphivcl development

    I asked you to submit an issue at Embarcadero/DelphiVCL4Python: Delphi's VCL library as a Python module for building Windows GUI (github.com), but you did not bother... The modules are built from this directory: python4delphi/Modules at master · Embarcadero/python4delphi (github.com)
  5. pyscripter

    Python4Delphi Tutorials/Information

    Look at the tutorials python4delphi/Tutorials at master · pyscripter/python4delphi (github.com) and demos python4delphi/Demos at master · pyscripter/python4delphi (github.com). You will also find a lot of stuff in python | Embarcadero RAD Studio, Delphi, & C++Builder Blogs
  6. pyscripter

    Class properties

    I tried to do something like class Test protected class function GetValue: string; virtual; public class property Value: string read GetValue; end; and I got a compiler error message stating the class property read specifier has to be either a class var or a static class method. Any idea about the reason for this restriction?
  7. pyscripter

    Class properties

    This looks like an inconsistency in the language with regard to class methods and class properties. And I don't think it is documented.
  8. pyscripter

    Class properties

    You access class properties through a class or an instance reference. That reference could be passed to a virtual class getter. Why do they have to be static? This is my question. A related question. How do virtual class methods work? Is there an equivalent to VMT for classes? By the way this works correctly: class Test protected class function GetValue: string; virtual; public property Value: string read GetValue; end; i.e. a normal property with a virtual class getter
  9. pyscripter

    SynEdit preferred version?

    Good suggestion. Go to Next/Previous modification Editor commands · Issue #165 · TurboPack/SynEdit (github.com)
  10. pyscripter

    SynEdit just got a major uplift

    This is correct, but this is the reason GPU support is disabled by default: D2D1RenderTargetProperties( {$IFDEF GPUSupport} D2D1_RENDER_TARGET_TYPE_DEFAULT, {$ELSE} D2D1_RENDER_TARGET_TYPE_SOFTWARE, // much faster in my desktop with a slow GPU {$ENDIF} As far as CPU utilization goes, I have tried with a 10K lines pascal file with highlighting, code folding and indentation lines. Scrolling by pressing continuously the Page Down key results in CPU utiliization around 5% (I7 12700). With GPUSupport enabled (currently incompatible with Gutter.ShowLineNumbers - will be fixed), CPU utilization remains close to 0% but GPU utilization rises to 5% (Intel UHD 770).
  11. pyscripter

    SynEdit preferred version?

    I will ask Embarcadero to update the Getit packages once the current versions is thoroughly tested and optimized, probably in a few weeks time. But the latency you mentioned is always going to be there, since the development is currently very active. So if you want the latest fixes and improvements do use the Github version.
  12. pyscripter

    SynEdit just got a major uplift

    This is not the experience here and in the other testers. Performance with highlighted 10000s of lines is very good. Could you please submit an issue at the Issue Tracker with sample project and text file?
  13. pyscripter

    Spell Checker implementation?

    There were many options mentioned in this thread, but there was no mention of the most obvious one at least on Windows: the built-in Windows spellchecker available since Windows 8. There many advantages compared to the options discussed here. It is free. Very easy to use. Minimal code to add to your project. No need to distribute dictionaries. If the user wants a given language dictionary they can get it through Windows language settings. It persists words added, ignored and autocorrected. It detects duplicate words. I got the idea from Ian Boyed's answer in this Stackoverflow question, but I could not find a Delphi translation of the Windows Spellcheck API. So I created my own. It is included in the attached zip file, along with a demo program. SpellCheck.zip
  14. pyscripter

    SynEdit just got a major uplift

    I suppose it does a bit. FMX is using DirectWrite on Windows, and its graphics engine matches the constructs of DirectX (FMX.Canvas.D2D). One would have to create a VCL abstraction of DirectX that it is similar (possibly identical) to that of FMX. It could be based on Vcl's Direct2DCanvas. That would be useful in porting not just SynEdit but other components from Vcl to FMX and the opposite.
  15. pyscripter

    TSynEdit - Custom Highlighter

    - Update your SynEdit to the latest version from TurboPack/SynEdit: SynEdit is a syntax highlighting edit control, not based on the Windows common controls. (github.com) - Look at the SynGen folder. The file Highlighters-HowTo.htm explains the basic steps. You need to create a grammar file and then SynGen.exe will generate your highlighter.
  16. pyscripter

    Direct2D 1.1 canvas much slower that Direct2D 1.0

    I see you are using ID2D1HwndRenderTarget. However your project also refers to Vcl.Direct2D_1 which should be ..\..\Direct2D_1\Vcl.Direct2D_1.pas but that directory is not part of the project. I wonder whether you can share that as well.
  17. pyscripter

    Direct2D 1.1 canvas much slower that Direct2D 1.0

    By the way FMX graphics on Windows are based on DirectX and they use the IDXGIDevice stuff (units FMX.Context.DX11 and FMX.Canvas.D2D).
  18. pyscripter

    Direct2D 1.1 canvas much slower that Direct2D 1.0

    It has been a while, but did you get a better understanding of the differences in the two approaches and the reasons for the slowness?
  19. pyscripter

    Place image in a TImage

    Demo 29 might be of help.
  20. pyscripter

    [FMX] Dll not found

    Looks like it is looking for python3.3. This is no longer supported. Just check the properties of TPythonEngine. Is UseLastKnownVersion checked?
  21. pyscripter

    Can't execute from ... import

    See MaskFPUExceptions · pyscripter/python4delphi Wiki (github.com)
  22. Something like Module := Import(ModuleName) if Module.__dir__().Contains(FunctionName) then Module.FunctionName()
  23. Wrong assumption. You need to call Free on the Python side or free it from Delphi. You can examine the ownership of a Delphi object in Python using the __owned__ attribute. If __owned__ is true it will be freed automatically. When you wrap objects yourself using DelphiWrappper.Wrap, you can specify the ownership. But here you are returning the object as a function result and you cannot tell who owns the object. Objects returned as function results or by accessing properties are wrapped using Wrap(obj, soReference);
  24. Wrapping of TStrings is fully supported. You can easily turn it into a Python list if needed. Look at Demo 31, python function testTStrings.
  25. The TPythonModule is for using Delphi stuff in python scripts. To get started, look at the tutorials and demos.
×