Jump to content

Stefan Glienke

Members
  • Content Count

    1362
  • Joined

  • Last visited

  • Days Won

    129

Everything posted by Stefan Glienke

  1. TValue has no implicit casting rule for integer -> enum - thus it raises the invalid cast exception because you are passing an Integer to SetValue which gets implicit put into a TValue which gets transported further. It later does a type/cast check against the actual type of the property and fails. See TValue.Cast or TValue.TryCast and the Conversions matrix for more details. I mentioned this many times: TValue is not Variant - it only supports implicit type casts that also the language supports and Integer to Enum type and vice versa is not directly assignable. procedure SetEnumProp(Instance: TObject; const PropName: string; const Value: string); var c: TRttiContext; t: TRttiType; p: TRttiProperty; typInfo: PTypeInfo; enumValue: Integer; v: TValue; begin t := c.GetType(Instance.ClassInfo); p := t.GetProperty(PropName); typInfo := p.PropertyType.Handle; enumValue := GetEnumValue(typInfo, Value); v := TValue.FromOrdinal(typInfo, enumValue); p.SetValue(Instance, v); end;
  2. Stefan Glienke

    Delphi and "Use only memory safe languages"

    This is why many modern and widely used languages have settled on using garbage collection (an automatic memory reclamation system) - because then the runtime deals with that and not the developer.
  3. My general advice to this is usually to move any conditional unit usage to its own unit and then only reference that unit in the dpr. Unfortunately, that is not some practice the DUnitX Expert is using. It would possibly also reduce the duplicated code generated for the dpr main every time.
  4. Imagine you could write this code in Delphi: var i: Integer = 42; begin const j = i; Writeln(j); end. Oh, wait, you can. Too bad that the syntax is not really clean as it mimics the const declaration using the equal sign while it really is what other languages call immutable variable and thus should have used the assign operator but people with even less expertise in programming language design than me disagreed.
  5. Unless you show the benchmark code any results you mention are pointless because there can be so many things in the benchmark that lead to bias. You could for example run IntToStr in a loop and this will lead to using the same already allocated string over and over.
  6. Stefan Glienke

    DelphiLint v1.0.0 released!

    However, it might not be permitted to do so in corporate environments.
  7. Stefan Glienke

    Unsafe code 'String index to var param'

    See https://stackoverflow.com/a/37688891/587106
  8. Stefan Glienke

    x87 vs SSE single truncation

    I did not read all of it but here is a bit of information on that subject.
  9. Stefan Glienke

    x87 vs SSE single truncation

    Differences in microbenchmarks can have all kinds of reasons (*) - when talking about the performance of single instructions you never estimate them from some possibly flawed microbenchmark but consult the instruction timings table (search for CVT(T)SS2SI) - the fact that truncate and non-truncate are always listed together makes it obvious that they perform exactly the same. (*) code alignment or address of the measured functions being one of the many reasons that can easily make some small or significant differences in the results All these tiny gotchas are the reason why many people don't like microbenchmarks. They are one tool for measuring but don't tell the ultimate truth - especially when it comes down to only a few instructions. That being said here are the results from an i5-13600K: x86 ----------------------------------------------------------------------------- Benchmark Time CPU Iterations ----------------------------------------------------------------------------- FastTrunc/Trunc:10910016 5585 ms 3703 ms 1 FastTrunc/FastTrunc_SSE2:10910032 2081 ms 1234 ms 1 FastTrunc/FastTrunc_SSE41:10910120 2158 ms 1047 ms 1 FastTrunc/SlowTrunc_SSE2:10910048 4193 ms 2641 ms 1 x64 ----------------------------------------------------------------------------- Benchmark Time CPU Iterations ----------------------------------------------------------------------------- FastTrunc/Trunc:12750304 5793 ms 3750 ms 1 FastTrunc/FastTrunc_SSE2:12750336 4775 ms 3656 ms 1 FastTrunc/FastTrunc_SSE41:12750432 6364 ms 4703 ms 1 FastTrunc/SlowTrunc_SSE2:12750352 4808 ms 2703 ms 1 Take these results with a grain of salt and keep in mind two things: - Spring.Benchmark still has some issues when running on Intels hybrid CPUs (12th and 13th gen) - I can trick a bit with setting Thread Affinity masks to run only on P-Cores but sometimes the times are a bit off - on x64 we might experience the behavior of implicitly converting Single to Double and back - I did not inspect the assembly code.
  10. Stefan Glienke

    x87 vs SSE single truncation

    Isn't this all that is needed? function FastTrunc(Value: Single): Integer; asm {$IFDEF CPUX86} movss xmm0, Value {$ENDIF} cvttss2si eax, xmm0 end;
  11. Stefan Glienke

    DelphiLint v1.0.0 released!

    Is it still not possible to create self-contained executables with Java? If so it would be nice because that would remove the requirement for the JRE.
  12. Stefan Glienke

    Variable not initialized?

    https://docwiki.embarcadero.com/Libraries/Athens/en/System.SysUtils.TStringHelper.TrimLeft
  13. Stefan Glienke

    Anonymous methods as interfaces

    Yes you can, the first post in this thread contains the code doing exactly that. In fact, until some version a few years ago it was possible to call Invoke. Still, if the method reference type has {$M+} enabled you can get RTTI for its Invoke method and dynamically invoke it. And there are more than one (Spring) libraries that do that. Also please let's get the terminology right - this is something that hugely annoys the heck out of me - because when talking about this subject everything is being called anonymous method but is incorrect. TProc = refererence to procedure; This is a method reference type - yes, even the official documentation is a mishmash. There is nothing anonymous about this type - it has a name: TProc. procedure Foo; begin end; var p: TProc; begin p := Foo; end. Again there is no anonymous method in this code - the variable p of the method reference type TProc is being assigned. The variable has a name and thus also is not anonymous. var p: TProc; begin p := procedure begin end; end. Now we have an anonymous method - the code block assigned to p has no name. This is an anonymous method that is assigned to the method reference variable p. Also see: https://en.wikipedia.org/wiki/Closure_(computer_programming)#Anonymous_functions https://en.wikipedia.org/wiki/Anonymous_function
  14. Stefan Glienke

    Anonymous methods as interfaces

    As someone using this "feature", I can tell you that the moment they break it I will pester them with issue reports until they revert this "fix". There has been another hidden "feature" in the past: adding operator overloads to records via helper when they are named in a particular way - since a few Delphi versions you can do that natively by declaring operator overloads on record helpers without this "hack" - but the hack still works. Since there is no official language specification and it's basically "if it compiles, it's valid code" I assume this to be added to the documentation rather than to be changed. Embarcadero has not changed things that are worse for backward compatibility reasons in the past so I assume they won't touch this either. The more important thing they should address with anonymous methods is this: not allocating any heap memory when no capturing is happening. The code would look similar to that for the comparers for intrinsic types in System.Generics.Defaults.pas
  15. Stefan Glienke

    How to quickly hash growing files

    SHA1 is dead. I suggest using SHA2 or SHA3 even if it is "just" for a file checksum. If you want performance-optimized implementations I would suggest using mormot2. uses mormot.core.buffers, mormot.crypt.secure; ... HashFile(myFileName, THashAlgo.hfSHA256); Fun fact: mormot2 SHA256 is faster than RTL SHA1.
  16. Stefan Glienke

    RTTI Context can't find an interface

    Nice, never heard of it before but I enjoy looking at libraries that have Spring as their dependency I submitted some improvement suggestions in the area we discussed here.
  17. Stefan Glienke

    RTTI Context can't find an interface

    It is because the compiler does not keep typeinfo of types that are only used as generic parameters in generic types in the public typeinfo list (which is what FindType with a qualified name iterates). If you had included the code for that Unmarshal I could probably give more advice on how to implement it best given that you seem to have support for spring collections in there
  18. Stefan Glienke

    Delphi and "Use only memory safe languages"

    This would be called Tracing garbage collection. But as Dalija already explained the crux is not which way of automatic memory reclamation is being used but the fact that it would be a mix of different ones that don't play together nicely.
  19. Stefan Glienke

    RTTI Context can't find an interface

    Why look up the type by full-qualified name in the first place? Every spring collection has the ElementType property that returns a PTypeInfo.
  20. Stefan Glienke

    Can LoadResString be done according to language ?

    Yes, it can if you are using resource DLLs - see https://docwiki.embarcadero.com/RADStudio/Athens/en/Localizing_Applications
  21. So assuming that your code scales linearly it will only take 92 days for 1 billion rows
  22. Stefan Glienke

    What new features would you like to see in Delphi 13?

    Looks like nobody ever corrected that statement with the introduction of generics - because then even changes in the implementation section are an interface breaking change. They experienced that themself with the 10.2.2 update where some bug in TArray.Sort<T> was fixed which caused issues so the update was pulled and corrected iirc.
  23. Stefan Glienke

    What new features would you like to see in Delphi 13?

    Niklaus Wirth just turned over in his grave about this proposal.
  24. Stefan Glienke

    Delphi and "Use only memory safe languages"

    With the exception that ARC is one of the worst ways of doing that - here are some reasons.
  25. This is nothing new - it's called Eytzinger Layout.
×