Jump to content


  • Content Count

  • Joined

  • Last visited

Community Reputation

19 Good

Technical Information

  • Delphi-Version
    Delphi 11 Alexandria

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. @PeterBelow Thank you for that! It works perfectly.
  2. This is going to sound like a homework assignment, but it's actually needed for some ZeosLib code to handle PostgreSQL client library digital array format. The array information is the following: NDims: The number of dimensions: Example: 3 DimArray: An array of dimension sizes. Example [1,2,2] ItemsArray: An array of data items (say Integer.) Example: [1,2,3,4] I'm trying to figure out an algorithm to turn the information above into a string that has a format like: {{{1,2},{3,4}}}. I've got it working for 1 and 2 dimensions, but it seems like I'm brute forcing it when it seems like a more clever approach should be possible. Any tips, hints, or psuedo-code (or actual code!) appreciated!
  3. A good way to test or discover this kind of bug is to use FastMM's allocate TopDown feature.
  4. MarkShark

    SynEdit just got a major uplift

    It sounds like it's a component streaming property error. Make sure to open each form that has a SynEdit on it in the Delphi IDE and then save the form. That should fix any of those types of errors. Another thought is to make sure you have the latest version and to build and install the packages.
  5. I realized in my benchmarking above that I was comparing a case insensitive dictionary to a case sensitive one. After correcting that the performance improvement for using this technique is 30%, which is still significant, but not what I reported above for sure lol. I do notice something odd. I'm loading about 300 SQL keywords (select, from, etc.) into a dictionary<string, integer> and if I check FKeywords.Collisions I'm getting a result of 90. Looking at the code for TDictionary it looks like they take the results of the hash and convert it a positive integer for the array of buckets (I hope that's the correct terminology.) I *think* that's where the collisions come in. It looks like Spring4d doesn't have the collisions property, so I haven't been able to do a sanity check against it.
  6. @Stefan Glienke Thank you! My code is very close to yours, which is a nice validation for me lol. I also put the "stored" string in the record (@Frost I also tested keeping them in a separate list to remove the record being managed, but it didn't seem to make any difference when I benchmarked it.) I would be using Spring4D for this in my own code, however it may end up in SynEdit's highlighters and so I'm trying to keep dependencies down and to leverage the rtl as much as possible.
  7. Excellent, thank you! I realize now that this is what Frost meant in his initial suggestion above and thank you Remy for that confirmation and link. I've done exactly what was suggested with the record as key and a custom equality comparer. Seems to work great and is still three times faster than my original version. Awesome!
  8. My technique above (using a hash as the key in a TDictionary) seems to work, however, it assumes that hashing my tokens will always give a unique value. Am I correct that that's a problem? Any thoughts on how to handle it?
  9. Thanks all! I ended up using Frost's suggestion of using the hash as the key like so: Hash := THashFNV1a32.GetHashValue(FTokenStart^, FTokenLength * SizeOf(Char)); if not FTokenDictionary.TryGetValue(Hash, Result) then Result := UnknownToken; And it appears to be roughly three times faster than my old verson using SetString! I used that particular hash because it looks like that's what Delphi's default string comparer uses.
  10. Hi all! I often find myself needing to look up a string token in a dictionary. Usually, the token is part of a larger string being parsed. Currently I take a copy of that portion of the string using SetString or Copy and use that new string for the lookup. The code looks something like this: // Not shown: parse some source string and get a pointer to the first char of the token and the length of said token // Now get a copy of that token so we can look it up in the dictionary SetString(TempToken, FTokenStart, FTokenLength); if not FTokenDictionary.TryGetValue(TempToken, Result) then Result := UnknownToken; I'm wondering if there's any way to avoid the SetString part of this. Thanks for any ideas!
  11. Wow, great answer! I used the LocaleCharsFromUnicode suggestion as I ended up needing to support some other codepages. Works great! Much appreciated!
  12. Hi all! I'm doing the following to convert a string to utf8 and then to move it into a memory location (it happens to be a globalallocbuffer for a clipboard format, but I don't' think that matters to my question.) It works well, but I was wondering if it's possible to do it without the intermediate byte array. Delphi 11 btw. Any thoughts appreciated. Buf := TEncoding.UTF8.GetBytes(AString); Move(Buf, PtrData^, Length(Buf));
  13. MarkShark

    SynEdit just got a major uplift

    @pyscripter went above and beyond with these improvements!
  14. MarkShark

    String optimization

    Wow! I've actually been bitten by strlen in the past. Well done sir!!
  15. @pyscripter, you pointed me in the right direction, but I think your syntax is off (I'm guessing just a typo.) Here's what worked: var SList := Shared.Make<TStringList>(TStringList.Create(dupIgnore, True, False)); Unlike some of my other tries this one just creates a single StringList with the correct parameters. I mention that just because some of my other syntax tests created a parameter-less StringList, immediately freed it, and then created the dupIgnore one. This syntax above seems to do the trick! Thanks! Also @Vincent Parrett I think you're right about Shared<>.Make! It turns out I was using the wrong "thing". Shared.Make<> vs Shared<>.Make.