Jump to content

David Heffernan

Members
  • Content Count

    3738
  • Joined

  • Last visited

  • Days Won

    188

Everything posted by David Heffernan

  1. This is correct. Raw pointer in C++ is directly analogous to typer pointer in Delphi. However a reference to a class instance is actually no different from a raw pointer. You have to manage allocation and deallocation of both. Which is my point.
  2. How is this materially different? You still need to explicitly Free, and you need try/finally. The class is just extra baggage. For what gain?
  3. David Heffernan

    How to enable SafeSEH, CFG flags for Delphi 10.4 Dll's/Exe's?

    That's what I thought. What about the part that pointed out the futility of setting the flag without having the corresponding compiler support?
  4. David Heffernan

    Strang problem with Delphi 12 IDE

    You are searching with the "regular expressions" check box enabled, hence the message
  5. Hmm, sucks to be you rn!!
  6. This sounds like a pretty unfortunate design choice. But since your compiler knows the layout of those records you can just work with the record types and the compiler takes care of the layout.
  7. It's actually very easy to predict this, once you know the rules. There is a good reason. Instead of ranting, maybe you should assume that the people that designed this knew what they were doing and that you just don't understand it. The question I have for you, is why are you so interested in size and layout of the records. What is motivating your interest. That might be helpful for us to understand.
  8. I have routines to do that. Because the Delphi code to convert between text and floats is irredeemably broken. I'm using dragon4 for float to text, but these days there are better algorithms around. I use dtoa in the other direction. My code base is spewing out a lot of floats to text files and yes it makes a significant difference to performance. Especially for files on a local drive.
  9. Kind of irrelevant whether it's heap or stack. Just that you avoid the heap allocation.
  10. David Heffernan

    ForEach runs only one "thread" at time

    The funny thing here, to my mind, is that I'd have expected that the first thing you did would have been to replace the actual function with a pointless work tasks that span in a loop for a certain period of time. If you then found that the behaviour was the same, i.e. not using all processor resources, you would know that the issue was in the library, or how you were using it. In fact had that been the case you could have come up with a very short example to capture the behaviour. You'd probably then have had an answer in an hour or two.
  11. Yes, this is it. It's a very important use case though. Imagine writing large YAML or JSON files containing a lot of data. And then imagine trying to do the same with multiple threads with extra contention on a memory manager. The point is that you build IntToStr using a function like mine above. And publish both. This allows the consumer of the library to have both options. Even if avoiding heap allocation is something that is only done in a narrow set of circumstances, that doesn't render it unnecessary.
  12. David Heffernan

    Delphi 12 is available

    I guess all the software that I've released in recent times didn't happen because I was using a useless tool.
  13. David Heffernan

    ForEach runs only one "thread" at time

    Is CompressFile CPU bound? Are we supposed to know what is in there? Seems like it would be important?
  14. This is all documented. Obviously we can tell you the answers but once you know about New, you can read the documentation to find out the rest of the details. It's really useful to know how to do that.
  15. David Heffernan

    Python <-> Delphi

    If it can be done in Delphi then it can be done In Python
  16. David Heffernan

    random between a range

    value2, value3, value 4 all have an off by one error.
  17. From my codebase: // disable range checks and overflow checks so that Abs() functions in case Value = Low(Value) {$R-} {$Q-} function CopyIntegerToAnsiBuffer(const Value: Integer; var Buffer: array of AnsiChar): Integer; var i, j: Integer; val, remainder: Cardinal; negative: Boolean; tmp: array [0..15] of AnsiChar; begin negative := Value<0; val := Abs(Value); Result := 0; repeat DivMod(val, 10, val, remainder); tmp[Result] := AnsiChar(remainder + Ord('0')); Inc(Result); until val=0; if negative then begin tmp[Result] := '-'; Inc(Result); end; Assert(Result<=Length(Buffer)); i := 0; j := Result-1; while i<Result do begin Buffer[i] := tmp[j]; Inc(i); Dec(j); end; end; function CopyIntegerToWideBuffer(const Value: Integer; var Buffer: array of WideChar): Integer; var i, j: Integer; val, remainder: Cardinal; negative: Boolean; tmp: array [0..15] of WideChar; begin negative := Value<0; val := Abs(Value); Result := 0; repeat DivMod(val, 10, val, remainder); tmp[Result] := WideChar(remainder + Ord('0')); Inc(Result); until val=0; if negative then begin tmp[Result] := '-'; Inc(Result); end; Assert(Result<=Length(Buffer)); i := 0; j := Result-1; while i<Result do begin Buffer[i] := tmp[j]; Inc(i); Dec(j); end; end; function CopyInt64ToAnsiBuffer(const Value: Int64; var Buffer: array of AnsiChar): Integer; var i, j: Integer; val, remainder: UInt64; negative: Boolean; tmp: array [0..23] of AnsiChar; begin negative := Value<0; val := Abs(Value); Result := 0; repeat DivMod(val, 10, val, remainder); tmp[Result] := AnsiChar(remainder + Ord('0')); Inc(Result); until val=0; if negative then begin tmp[Result] := '-'; Inc(Result); end; Assert(Result<=Length(Buffer)); i := 0; j := Result-1; while i<Result do begin Buffer[i] := tmp[j]; Inc(i); Dec(j); end; end; function CopyInt64ToWideBuffer(const Value: Int64; var Buffer: array of WideChar): Integer; var i, j: Integer; val, remainder: UInt64; negative: Boolean; tmp: array [0..23] of WideChar; begin negative := Value<0; val := Abs(Value); Result := 0; repeat DivMod(val, 10, val, remainder); tmp[Result] := WideChar(remainder + Ord('0')); Inc(Result); until val=0; if negative then begin tmp[Result] := '-'; Inc(Result); end; Assert(Result<=Length(Buffer)); i := 0; j := Result-1; while i<Result do begin Buffer[i] := tmp[j]; Inc(i); Dec(j); end; end; {$IFDEF RANGECHECKSON}{$R+}{$ENDIF} {$IFDEF OVERFLOWCHECKSON}{$Q+}{$ENDIF} No heap allocation. I guess I could avoid that DivMod now and do something better. The main point is that a good runtime library should have building block functions like this that allow us to perform such conversions without forcing heap allocation. The RTL should have functionality like this on top of which all conversion functions can be built. Then the RTL function can be optimised and everyone benefits.
  18. The biggest issue with the Delphi code is that it forces heap allocation on you which is the real bottleneck.
  19. David Heffernan

    Delphi 12 is available

    So it's just an issue of deployment. Fair enough. I guess there's a bit of complexity in deploying applications well.
  20. David Heffernan

    Delphi 12 is available

    What are these priceless advantages? And anyway there are loads of other compilers and toolchains that do this.
  21. David Heffernan

    2 new programs

    Why wouldn't people just use standard libraries and tools for this?
  22. David Heffernan

    Delphi Version in profile

    I will never understand how it got released ever. Do they not know how to write tests?
  23. David Heffernan

    Delphi Version in profile

    Were just waiting for somebody to start using it I guess
  24. David Heffernan

    Win 64 debugger not working

    That fabled focus on quality really paying dividends.
  25. Nobody seems yet to have wondered whether the potential for behaviour change is important. This is an ill posed question with no possible answer because we don't know any detail. So much heat, so little light.
×