Jump to content

Marat1961

Members
  • Content Count

    73
  • Joined

  • Last visited

  • Days Won

    1

Marat1961 last won the day on October 14 2020

Marat1961 had the most liked content!

Community Reputation

17 Good

About Marat1961

  • Birthday 05/16/1961

Technical Information

  • Delphi-Version
    Delphi Community Edition

Recent Profile Visitors

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

  1. I completely agree that this approach has a right to life. If the client code is written by you, if you never make mistakes. That is, if the target, for example, was allocated on the heap, if the target is not part of a packed record, etc. But if you write that your procedure guarantees atomicity (judging by its name). I think a check will not hurt. From the point of minimizing the code, it is better to insert checks at the beginning of the procedure. Well, at least observe the minimum decency and insert Assert into debug mode.
  2. Contract programming. The simplest version of the contract is preconditions - requirements that must be met before a specific action. The method must check the validity of the passed parameters. https://en.wikipedia.org/wiki/Design_by_contract
  3. I also find it interesting to use the function function InterlockedSetDouble(Value: double): double; begin if (@Result and $7) = 0 then Result := Value else ...
  4. It seems naive to me to hope that var parameter will be aligned. At a minimum, I would insert a check
  5. Due to the causal relationship, it seemed logical to me to discuss here. 1. The atomicity of the data assignment operation is ensured if the data is aligned on the double word boundary. 2. The data is aligned if ..
  6. don't worry, be happy When passed through the stack, parameters will be aligned on the 8-byte boundary if the parameters are passed by value and one of the following conditions is met: 1. all parameters are multiples of 8 bytes 2. optimization enabled 3. 64 bit mode Therefore, I would exclude passing by var and passing two double parameters. This would ensure that the values are aligned in memory.
  7. He who is forewarned is armed. For a long time I was looking for an error when using the Windows API due to the fact that the parameter was not aligned on the boundary of a 32-bit word. procedure InterlockedSetDouble(var target: double; flag: Byte; Value: double); I think now Value will be misaligned
  8. The variable must be allocated on the heap. If it is a local variable, we have no guarantee that it will be aligned. By the way, under certain conditions, the parameter passed by value may also be misaligned.
  9. Marat1961

    Hashing Street Addresses ?

    If you want to get hash of an object by key fields, it is convenient to serialize these fields, e.g. in TMemoryStream or even string. Then use reliable hash function, for example SHA-3. Fields can be numbered, empty values can be skipped '1:France;3:Paris'. For strings, a function that takes string length in characters into account when calculating the hash is useful. For floating point numbers, it is better to use an algorithm that hashes the exponent and the mantissa of the number separately. If it's an object or a record, sometimes it makes sense to write your own function that hashes selected key fields of the object.
  10. Marat1961

    Hashing Street Addresses ?

    There can be several addresses in a house and they all have the same geodata.
  11. The search speedup for hashmaps in this case is ~ 1/N, where N is the size of the table. As long as the table is not completely filled with less than < 0.7 the table works well, and then comes performance degradation. In such cases, the table size is increased and all data is moved to the new table. This takes extra time and also means that while you do this, your system will not be able to serve clients. In my opinion, up to about 16 elements, it is better to use a regular unsorted list and a linear search. Then it makes sense to use either a TList with sorting each time a new key is added, ~ N * log2(N) for quicksort, or a tree where search and insertion with order maintenance is an inexpensive log2(N). Advantages of hashmaps. Search time for hashmap includes: hash generation + 1 to m equality comparisons. Ideal hash function: 1. must be fast 2. Does not create collisions (does not generate the same key for different keys). I have compared many hash functions in my time and realized that even the simplest ones provide good results on real data. I have tested it on a database of addresses with about a million entries and for a client base with about 500,000 entries. The algorithms included md5, sha-2, sha-3, src32, multiplicative hash. function HashMultiplicative(const key: PByte; Size: Cardinal): Cardinal; var i, hash: Cardinal; p: PByte; begin hash := 5381; p := key; for i := 1 to Size do begin hash := 33 * hash + p^; Inc(p); end; Result := hash; end; For strings, a function that takes string length in characters into account when calculating the hash is useful. For floating point numbers, it is better to use an algorithm that hashes the exponent and the mantissa of the number separately. If it's an object or a record, sometimes it makes sense to write your own function that hashes selected key fields of the object. I like hash table implementations with chains. I usually know the approximate number of objects in the system and can immediately set the required input table size N. This will require a bit more memory, but you know right away what the speedup will be and there will be no time wasted on dynamically increasing the table. There is no point in increasing the size of the table much more than N. Since the input index is determined by the search index_input := hash mod N; You can't choose a table size multiple of a byte, it increases the crowding of data in the table. For many hashing algorithms, if you choose a size other than a prime number, the probability of collisions will increase and it will degrade the statistics.
  12. After one of the releases of our program was hacked about 15 years ago and posted the hacked version on FTP. We protect our code with a protector. I think our company uses Enigma now. There have been no more such hacks since then. At least the code must be digitally signed and its integrity must be verified. If something goes wrong, we check some flags somewhere and the program changes its behavior (works incorrectly). It may crash after a while, modal windows stop working well, etc. Separate out the fact of tamper detection and where things will work differently should be placed as far as possible in time and scattered across the code.
  13. tPolar2D = record Radius: Double; azimuth: Double; end; forward; //keyword just to say there are methods to be defined later In my opinion, this is not the most successful design. A radical solution is needed. It is much better to add a namespace. And inside the namespace, allow to refer to any declarations, regardless of the order of their declaration.
  14. PPoint2D = ^TPoint2D; PPolar2D = ^TPolar2D; constructor TPolar2D.From(const Pt: PPoint2D); constructor TPolar2D.From(X, Y: Double); constructor TPoint2D.From(const Pt: PPolar2D); constructor TPoint2D.From(Radius, Azimuth: Double); PNode = ^TNode; TNode = record next: PNode; end; var ppt: TPolar2D; cpt: TPoint2D; begin ppt := TPolar2D.From(@cpt); end.
  15. I certainly understand that many people did not program on a pure Pascal. Use pointers and you will be happy. Pointers to a record can be declared before the record is declared. Also if you pass a record as a parameter, there is no need to pass the value as it is extremely inefficient and the recording value is copied to the stack. Transmit the record by var or by const. PPoint2D = ^tPoint2D;
×