Jump to content

Kas Ob.

  • Content Count

  • Joined

  • Last visited

  • Days Won


Kas Ob. last won the day on October 25

Kas Ob. had the most liked content!

Community Reputation

175 Excellent

1 Follower

Recent Profile Visitors

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

  1. It looks like that, must be me as stupid person pretend to be a programmer, i didn't know the first rule of writing application.
  2. @Rollo62 I can't agree more, when i disagreed with Lars is about making it as Rule. Your point about errors, exceptions, logs..etc is completely valid and no one will argue with that, but not every application should follow such rule, example imagine opening Windows Task Manager and it does show an empty window then fill the information gradually, in other words some application are meant to be used for less than 1 minute, for me and such application it is a sin to waste 1 second delaying full functionality or at least most functionality online and ready for user action. I hate splash screen and rarely use them, away from that all users like it snappy and ready for action, of course some application might need a login, then this will simplify everything, then later the client ask for auto login with saved credential for faster online time, then i will skip login form and perform the login as sooner as possible to establish the secure connection while opening last opened windows by the user.
  3. Why is that ? What if the application need to parse folders for files, decompress or preload resources...or even connect to some server, must i leave the application to show then start doing this, or can i start do this in the background ? What i am trying to say is this thing, when trying to start doing something, is depends on what the application does, but i disagree on such rule. @Dany Marmur I use Nexus Quality suit Method Timer to get an idea where time been spend.
  4. Kas Ob.


    I was trying to be funny, like holding the compiler from his ear and point to some assembly code, and say bad boy !, bad boy!
  5. Kas Ob.

    Problem with BidiMode

    I found that adding RLM or ALM after words help building it right, it is not needed everywhere, but i wanted to find a simple rule to follow, procedure TForm10.Button2Click(Sender: TObject); const ALM=#$061c; RLM=#$200F; var st: string; begin st := '123 '; st := st + ' Sample '; st := st + RLM; st := st + ' 456'; Memo1.Lines.Add(st); Memo2.Lines.Add(st); st := '123 '; st := st + 'عينة'; st := st + RLM; st := st + ' 456'; Memo1.Lines.Add(st); Memo2.Lines.Add(st); st := '123 '; st := st + 'عينة'; st := st + RLM; st := st + ' Sample '; st := st + RLM; st := st + ' 456'; Memo1.Lines.Add(st); Memo2.Lines.Add(st); st := '123 '; st := st + ' Sample '; st := st + RLM; st := st + 'عينة'; st := st + RLM; st := st + ' 456'; Memo1.Lines.Add(st); Memo2.Lines.Add(st); end; Start there and see if you can build on that, but as i said i am trying things and don't know for sure if this is the right way to do it, if there is a way. And good luck.
  6. Kas Ob.


    Can't agree more, only one problem though, How to open ticket for the compiler to ask it for better job ? and may be to point few internet resources to read.
  7. Kas Ob.

    Problem with BidiMode

    My 2 cents on this, It is difficult to solve as it VCL is not much of help and OS is not helping too. To explain this, lets use this code to understand the problem first procedure TForm10.Button1Click(Sender: TObject); var st: string; begin st := '123 '; st := st + ' Sample '; st := st + ' 456'; Memo1.Lines.Add(st); Memo2.Lines.Add(st); st := '123 '; st := st + 'عينة'; st := st + ' 456'; Memo1.Lines.Add(st); Memo2.Lines.Add(st); st := '123 '; st := st + 'عينة'; st := st + ' Sample '; st := st + ' 456'; Memo1.Lines.Add(st); Memo2.Lines.Add(st); st := '123 '; st := st + ' Sample '; st := st + 'عينة'; st := st + ' 456'; Memo1.Lines.Add(st); Memo2.Lines.Add(st); end; Here the result Now we can have a glimpse what is going wrong and where i separated building st to make sure the editors involved in copying and moving the sentences are irrelevant, this is essential. From the result, you see clearly parsing and switching between words within a string can and does change the string printing output, even within Windows components the drawing behaviour does change, i remember also GDI/+ was doing things differently, but not sure for current versions and Windows 10, and which is which, that is a thing you should test for your self, things gets more ugly and less predictable with symbols. One thing though, i love how Alexander In his HTML Delphi Components include the full parser algorithms to handle switching from RTL words and LTR in the same string, but also the it does fail in few corner cases when some char that steer the the parser in other direction like '.' or a bracket, but my DHTML is expired and old, and i don't expect any perfect algorithm to exist at all, the thing of me having the code for parsing i can change things to fir my need, as these symbols can be chars LTR ranges encapsulating RTL words, i think you are familiar with most popular case with brackets. Another thing, in the above example you used Arabic numbers "123.." they called Arabic, while the Arabic languages most likely will use Hindu numbers "٠١٢٣٤٥٦٧٨٩", and using those will greatly change the behaviour in different places lets see the different behaviour procedure TForm10.Button1Click(Sender: TObject); var st: string; begin st := '١٢٣ '; st := st + ' Sample '; st := st + ' ٤٥٦'; Memo1.Lines.Add(st); Memo2.Lines.Add(st); st := '١٢٣ '; st := st + 'عينة'; st := st + ' ٤٥٦'; Memo1.Lines.Add(st); Memo2.Lines.Add(st); st := '١٢٣ '; st := st + 'عينة'; st := st + ' Sample '; st := st + ' ٤٥٦'; Memo1.Lines.Add(st); Memo2.Lines.Add(st); st := '١٢٣ '; st := st + ' Sample '; st := st + 'عينة'; st := st + ' ٤٥٦'; Memo1.Lines.Add(st); Memo2.Lines.Add(st); end; the result had changed Another thing there is special char to control such sentences called Right-to-Left Mark https://en.wikipedia.org/wiki/Right-to-left_mark You might want play and try to insert it between strings and see the effect in that page there is an example on how to add "!" at right place. That was my 2 cents, and really it depends on you understanding when the problem occur and how to find workaround, as i doubt the existence of a complete fix.
  8. Fine, means are you free to use the first one with extra unused parameter moving the allocating the managed type variable from the the intensively called function in a loop to the caller. I didn't suggest that you or anyone should use that everywhere, but if you to enhance a loop calling function with such variables then there is a workaround. I found myself using TStringList very often, it is great tool that can't live without, but when it does come to fast in intensive data processing i found recycling that list yield better performance, as such usage will remove the create and free, leaving me to call clear on exit, which the skipped destructor should called.
  9. just "fields" instead of "local field" the right wording of the question is when the last time you saw an object without fields that had been used in multithreading ?
  10. While it can, the impact is manageable most the time by default, see, you have an object, if the object doesn't use any fields of its own then you are free to use it in multithread way safely, of course if it is not calling unsafe outsider code ( objects, functions), so by introducing such approach by moving local var to object field, then yes it should be protected against parallel usage, but and this is big but, when the last time you saw an object without local field that had been used in multithreading !? those are rare. If these object does have fields then it is already protected and that field (converted from local) would not be a big difference. It is an approach to squeeze some juice, not ideal and it does add complexity, also comes with drawbacks like the one you pointing to, but how this is different from any algorithm we use on daily basis.
  11. I forgot to mention when it is not ugly but appreciated for speed with minimal cosmetic effect. When your function is a method in a class/record then move these local managed types vars to be private fields even when each one of them is not used outside one method, here you can recycle them, just remember they are initialized with some value from previous usage so be careful, like don't assume a string being used like that an empty one.
  12. It is just ugly, and the benefit is limited per your timing. There is a trick which is also ugly but more handsome ! The overhead of using string as local var in often called function might be small but can accumulate, so only if you want it, and for educational knowledge as trick and workaround, you can do the following: function ProcessString(const aStr: string; var unused: string): string; var i: integer; b: boolean; begin if flag then Exit(aStr); // dummy code to use the local variables unused := aStr; i := Length(unused); b := i = 1; if b then Result := aStr else Result := unused; end; procedure TheOneThatCallProcessString; var temp: string; begin for ... ProcessString('12', temp) end; This should fix your gain from splitting the function in both flag cases, the idea is to remove local managed var from this function to a parent/caller local one, so no more try..finally then clearing, this only can be helpful when you have fairly small number of callers to that function.
  13. Kas Ob.


    It is slower https://stackoverflow.com/questions/46762813/how-much-faster-are-sse4-2-string-instructions-than-sse2-for-memcmp But 1) The gain from removing the two conditional branching will totally worth it, because they are forward and one will be taken almost always, in other words that "ja @@Process" is anti pattern, and bad for branch prediction. 2) You can save these register in XMM registers, this is faster than pushing them on stack, or on any memory at all. Just an idea that worth investigating. What i am missing here? I have SandyBridge and it raise exception on vpgatherdq , and looking here https://www.felixcloutier.com/x86/vpgatherdd:vpgatherdq ,it is promoted as AVX512, what CPU do you have ? I read that but what i missed that it the xmm version of that instruction in the reference page, my bad, sorry for that.
  14. Kas Ob.


    @Mahdi Safsafi I think it can be far better with SIMD 1) use such barebone to remove the extra call dependency function HexToBinBareBone(const Value:string):string; procedure ToRaiseError(const Value:string); begin raise EConvertError.CreateFmt('Invalid hex digit found in ''%s''', [Value]); end; asm test eax,eax // Empty input string -> Empty result jz @Exit push edi //.. push edx // Value : string in stack , we keep this at last so we can access it with [esp] push eax // Value : string in stack , we keep this at last so we can access it with [esp+4] mov edx , [eax-4] // get length shl edx , 2 mov eax , [esp+4] mov ecx , offset system.@UStrSetLength call ecx mov edx , [esp+4] // restore result pointer mov edx , [edx] // edx -> result[1] mov eax , [esp] .. mov [edx],$00410042 // testing .. pop edx pop eax pop edi @Exit: ret @InvalidChar: pop edx pop eax // we need eax value to be the parameter passed to show the error message right pop edi jmp ToRaiseError end; 2) You build it to use lookup table while using SIMD is most valued benefit is to reduce memory access ( aka lookup table), so you are far better by calculating generating the 0 and 1 by masking. 3) This should be removed, why are you trying to check for NT while you have the length in of the string, so may be switching to explicit string compare instead of implicit will help here ja @@Process { either end (null terminated) or invalid char } test Word [eax + ecx *2], -1 // is NT ? => continue jnz @@InvalidChar 4) You used AVX512 instruction, my CPU is old and doesn't have either AVX2 or AVX512, couldn't run it, but keep in mind AVX2 and AVX512 does have huge hidden drawback, i think Stefan was pointing to with some may be hidden sarcasm intentionally or not, AVX2 and AVX512 in multi core concurrent usage can literally melt the CPU !, so the CPU will decrease its frequency, such decrease is not momentarily so the impact of over using AVX512 and AVX2 can be huge, to dig this further, start here https://stackoverflow.com/questions/56852812/simd-instructions-lowering-cpu-frequency 5) When i wrote my MMX version i thought how i miss the shuffle instruction that does exist with SSEx, but when i wrote XMM i forgot to use 🙂 , so the idea instead of manipulating a unicode char better to translate the Ansi equivalent (one byte) then generate the binary bit string one byte per char too, after that unpack them using shuffle to memory then interleave the zeros, such interleaving with two unpack, three SIMD instruction that will be executed in 1 cycle. 6) To convert from hex char to decimal byte value, a more simpler and faster algorithm can performed, as to subtract the ord('0') then you will have the mask value for those with 'FF' then just AND them, compare after subtraction for letters again for first char , i think you got the idea .... at last just Or them together and you will have your decimal values. I am sleepy now and can't open my eyes so i might missed something or wrote something wrong, for that i am sorry.
  15. Kas Ob.


    The thing is we already here and and Delphi IDE does and can utilize LLVM, so why on earth they neutered it, instead of using it right ! Just was looking for ideas then found some C code and decided to check how different compiler handle loop unrolling on their own, stopped checking after seeing the result of CLang 10.0 , the generated assembly made me very angry. Have a look for yourself https://godbolt.org/z/1cva96 LLVM can do magic like the above, and also can do unthinkable stuff, that should be the focus, if not for full project then just parts where developer deemed crucial, that is more useful than a linker, or shopping for $1000 of free software to bundle.