Jump to content

Dalija Prasnikar

Members
  • Content Count

    1061
  • Joined

  • Last visited

  • Days Won

    91

Posts posted by Dalija Prasnikar


  1. The whole situation at Stack Overflow just made a drastic turn for the worse:

     

    https://meta.stackoverflow.com/questions/425162/we-are-seeking-functional-feedback-for-the-formatting-assistant and https://meta.stackoverflow.com/questions/425081/stack-overflow-will-be-experimenting-with-a-question-formatting-assistant-and-w

     

    It seems that whole reason behind tying the mods hands when it comes to detecting and moderating AI content is related to the brand new "AI Formatting Assistant" It is presented as something that would help people write better questions, but I guess that is just first step and second one would be expanding it to answers, too. Because such "formatted" posts would have typical AI signature, moderators would not be able to distinguish between AI generated and "merely formatted" posts.

     

    Additionally, the results of "formatting" go beyond mere formatting because AI completely rewrites the post including text and code adding its hallucinations on top. It is beyond horrible and harmful.  

    • Like 2

  2. 4 minutes ago, havrlisan said:

    You're right, thank you. I did think that was the issue as you've written, but I thought it would be implicitly cast into IAncestorObject when either Added to TList<T> or when retrieved via First().

    The problem is that all variants of IGenericList<T> have same GUID so Supports function will succeed even though those different generic lists are not compatible.

    • Like 1

  3. There is not bug in compiler, but in your code.

     

    When you say 

    LCastedList.Add(TAncestorObject.Create)

    What will happen is equivalent of following code:

     

    var Tmp: IInterface := TAncestorObject.Create;
    LCastedList.Add(Tmp);

    This will be because LCastedList is declared as IGenericList<IInterface> and stores IInterface references.

     

    However when you retrieve stored reference you will call that on original list which is declared as IGenericList<IAncestorObject> and retrieved reference will be of type IAncestorObject and you can try to call LObj.ID on that retrieved reference. But in reality stored reference was IInterface, not IAncestorObject and it crashes when you call ID on it because that method (GetID) it simply does not exist there.

     

    Point of generics is that you have same type stored in the background, not to store incompatible types. even though there is same object behind those two interface references, those interfaces are completely different types represent different entry points to that object. Sometimes you can force "wrong" type to be stored at runtime, which is usually not what you should be doing, but if you do, you need to make sure that every time you retrieve something that might be "wrong" you cast it back to appropriate type.

     

        var
          LTmp := LList.First;
        var
          LObj: IAncestorObject;
        if Supports(LTmp, IAncestorObject, LObj) then
           var LID := LObj.ID ;

     

    • Like 1
    • Thanks 1

  4. 59 minutes ago, Tommi Prami said:

    Task manager It shows total memory of the process tree, so ide used little more than 1Gb of memory after it died. LSP processes used total of about gig. So total memory consumption peaked around 2Gb maybe slightly over, hard to tell, but it does not matter.

    LSP is separate process and it's memory consumption does no affect the IDE. Extracting that functionality outside and reducing IDE memory footprint was one of the reasons LSP was introduced in the first place.

    59 minutes ago, Tommi Prami said:

    This time I did not get Out of memory, butr IDE used all handles, and after that it ran for awhile, and just vanished.

    There is known GDI handle leak in Parnassus Navigator https://quality.embarcadero.com/browse/RSP-40986

     

    Also IDE is using a bit more GDI handles than it used to and it seems that it has some caching issues, where it caches the component icons but it does not have a cache limit and it does not release those that were not accessed in for some period of time. Opening plenty of forms and accessing many different components during design time can hit GDI handle limit. AFAIK you can increase that limit (I never had issues so I never tried it) https://stackoverflow.com/questions/38612364/how-to-increase-the-maximum-amount-of-gdi-object-for-windows-10

    • Like 1

  5. Since December Stack Overflow and other sites in the network have been spammed with AI generated answers which are usually incorrect while sounding plausible. To handle this problem moderators working with other users and Stack Overflow staff enacted the policy that bans all AI generated posts. Such posts are deleted and users can be suspended (usually for a week) for posting them. To get the better picture about the impact, we are talking about thousands of users and even more posts.  See: https://meta.stackoverflow.com/questions/421831/temporary-policy-chatgpt-is-banned

     

    However, last week the company enacted another policy which still allows moderators to moderate AI generated content, but effectively does not allow them to to use any means necessary for detecting such posts. In other words they can remove posts mostly if user admits post is AI generated. 

     

    Allowing AI posts on sites will effectively kill the sites and elected moderators have decided to take an action and go on strike, along with other users of Stack Overflow and other sites in the stack Exchange network. Strike is scheduled to start tomorrow on Monday, Jun, 5th. 

     

    Unofficial announcement of strike on Stack Overflow (there will be another announcement on the main Meta tomorrow)  https://meta.stackoverflow.com/questions/424979/what-has-happened-to-lead-moderators-to-consider-striking

     

    If you have Stack Overflow or other Stack Exchange account please support the strike and sign the strike letter at https://openletter.mousetail.nl/  Signing is made by automatic authentication with Stack Exchange network account through browser if you decide to sign. You will have to enter display name you want to be displayed on the letter as some people have different display names on different sites. 

     

    Thanks!

    • Like 11

  6. 52 minutes ago, Ian Branch said:

    My Customer wants all the Apps to operate to a standard format, interestingly, to en-AU, despite what the User may have done with his/her PC.

    If that is the requirement, then, yes, setting global FormatSettings variable will have that effect. You also need to change Application.UpdateFormatSettings to false, before you change global FormatSettings to avoid user changes to be applied if the application is already running.

     

    You also need to keep in mind that any code that does not use global FormatSettings will not be affected by changes in global variable. For instance Delphi JSON serialization uses fixed settings for serialization that are based on JSON format requirements. Any code that uses own settings will behave in similar way.

     

    I would still suggest that for serialization purpose and data persistence, you use separate FormatSettings variable as if (and when) specification changes and users are allowed to have their preferer format used for viewing purposes, it will be very hard to make separation afterwards and find all the places that need to use specific fixed format.

    • Like 1

  7. 6 hours ago, Ian Branch said:

    1.  If I set FormatSettings with a Country code, i.e. "var FormatSettings := TFormatSettings.Create('en-AU');", then that action will configure the various TFormatSettings properties in SysUtils to the Australian formats.

     

     

    No. If you say var FormatSettings ... you will declare new FormatSettingsVariable in the scope where you have written that code, that will have nothing to do with global FormatSettings variable. If you want to change the value of global FormatSettings variable you need to write FormatSettings := TFormatSettings.Create('en-AU')

     

    However, changing global FormatSettings variable is not advisable for several reasons:

     

    1. FormatSettinsg is populated with user's locale. You should honor the user settings and present data to the user in format user has specified, not the one you think it should be.

    2. If user changes locale settings while your application is running, those new settings will be applied to the global FormatSettings variable if the Application.UpdateFormatSettings is True (which it is by default)

    3. FormatSettings beging a global variable are not thread-safe and if any other code changes those settings (and there has been such code out in the wild) and code running in threads that uses the global will be affected. Using formatting and parsing routines that use FormatSettings passed as additional parameter is the best choice for avoiding thread-safety and other issues as you will have the control over which settings are being used.

    4. And the most important aspect, if you have code that relies on very specific values in FormatSettings, like serialization, should not depend on global FormatSettings variable but should have its own more scoped (and therefore more protected) TFormatSettings variable that will be set once and never change during the application lifetime. Using global FormatSettings for working with data that needs to be in some specific format is the fastest way to shoot yourself in the foot.

     

    6 hours ago, Ian Branch said:

    2.  I can then forget about the variable FormatSettings.

    No, you should not forget about it for reasons I specified above.

    6 hours ago, Ian Branch said:

    3.  Having set these properties in SysUtils, whatever Unit has SysUtils will have/use the set properties.

    Any formatting and parsing function that uses global FormatSettings variable will be affected by the change in global FormatSettings whether you change it or some other code. 

    6 hours ago, Ian Branch said:

    4.  Any function/procedure that uses a FormatSettings property will now use the relevant set TFormatSettings property according to the Country/Region code employed in the '.Create()'.

    Yes. If you use functions that rely on global variable, they will use whatever value at the time is in that global variable.


  8. 18 minutes ago, limelect said:

    He found using logcat ( why I did not think about it ?) that there are problems with the java

    So if compilation is OK how one is expected to debug? 

    Again, if application crashes inside Java wrapper side, then you cannot debug it with Delphi. You need to see what is exact error message and then Google what feature is this error connected to. Then look at changed requirements in the official Android documentation and make appropriate changes.  Because native Java applications also suffer from same issues when upgrading, usually you can find plenty of resources which will give you answer about precise configurations needed even without going through official documentation.

     

    Creating new Delphi application and then including those problematic features can also help to pinpoint exact problem. Most likely there is some configuration problem in your application manifest. But there could be other issues, like wrong JAR libraries and similar. 

     

    Once you get new Delphi application up and running, you can see the differences in configuration and apply necessary changes to the old one.


  9. 1 hour ago, limelect said:

    I do not see ANY reason for the transfer problem

    from D10.2.3 to D11. The components are standard

    And if professionals like all of us have to start with a learning curve

    it is not reasonable. After all, it is not like moving from

    D7 to D11.

    Android development is very different from Windows development. Most likely cause of problems are changes and requirements for newer Android OS that were introduced in the meantime. It has nothing to do with compiler nor Delphi language.

     

    Google releases new Android version every year and to comply with those new OS releases and ability to upload applications on Play Store, Delphi Android applications need to support new OS and new Android SDK. There have been numerous changes between 10.2.3 and D11.3 considering Android development and your old application most likely uses features that were subject to change and that require additional or changed configurations or code. Without knowing which features you are using, it is impossible to say what needs to be changed.

     

    You can find list of changes and new requirements between releases in official Android documentation https://developer.android.com/tools/releases/platforms 

     

    Also Delphi Android application runs inside a wrapper and if application crashes due to misconfiguration inside that wrapper, it will crash before any Delphi code starts running. That is why you cannot debug it. To understand what is happening and why it crashed you need to look at native Android error logs - logcat. 

    • Like 2

  10. 5 hours ago, Willicious said:

    LemGame is a different unit, it contains a (variable? property? field?) called CurrentIteration which, essentially, represents the current in-game frame.

    Without seeing where LemGame is declared and how it is impossible to say why you have an error. It is also important to note that sometimes you may get error in the IDE (read squiggly lines) in some perfectly valid code. You should always try to compile code to see real errors. also, when you do get compiler error, you should fix them in order they appear as the first error can cause subsequent issues for the compiler and it is possible that compiler will show more errors in otherwise valid code.

     

    But, it seems like your main problem is not with Delphi but with OOP principles in general as you are trying to access properties in a class without creating instance of a class. Class is just a template from which object instances are created. Before you create object instance data (class fields and properties) don't exist in memory, so there is nothing you can access there. The exception to that are class fields, properties and methods that are additionally marked with class descriptor. Those can be accessed directly. They are basically global variables that are organized under class namespace. See https://docwiki.embarcadero.com/RADStudio/Sydney/en/Properties_(Delphi)#Class_Properties

     

    Purpose behind creating object instances from class before using them is that most of the time you will need more than one. For instance, you can have one global object instance of a game, but you will need more instances of game characters or other game objects. 

     

    Think of it, class gives you description about attributes and functionality of a person, and when you construct object instances of that class you will get separate persons: Joe, Mike, Alice... 

     

    I would advise you to read a bit about Delphi language and some basic concepts. good place to start is https://learndelphi.org/ and Delphi Language Guide https://docwiki.embarcadero.com/RADStudio/Sydney/en/Delphi_Language_Reference 

    • Like 1

  11. 18 hours ago, Ian Branch said:

    I don't really understand what goes on in Threads and therefore what you can and can't do.

    If you need to loop some code x times and break out on some condition, then the simplest logic would be:

     

    
    for i := 0 to x do
      begin
       if TEDBEngineSessionManager(DBSWhoIsOn.Handle).TryLock(1) then
         begin
           ...
           // if succesfull break out of the loop
           Break;
         end
       else
         TThread.Sleep(500);
      end;

     

     


  12. 2 hours ago, Marus said:

    I want to send a message, from worker thread to the main thread queue, with a string in it.

    Possible solutions in your scenario depends on what kind of string are you sending. Is it a predefined constant, or it is provided by the code in a thread, do you already have it in a string variable and just need a copy for posting., how large are those strings, is the data in string critical or is it just some discardable notification, what is your logic if there is not enough memory...

     

    Thanks for the compliments.


  13. 11 hours ago, Marus said:

    I need a safe way to allocate memory for a string variable, without getting exceptions. I don't want to use "try-except" blocks and neither the function that do this, use them internaly. I need a speed optimised method. If there are errors it can return a nil pointer.

    What exactly are you trying to do? This sounds like XY problem. See https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem

     

    Out of memory exception is recoverable if your application logic allows that at the moment it happens. For instance if there is enough free memory to do regular work, but there is not enough to load and process some large file user tries to open. This is why exception handlers are here for.

     

    So if you can logically recover from failing to allocate large string, you can just do the same using exception handlers. There will be no memory corruption when string allocation fails that will have negative effect on your application. While exception handling does have some small impact on performance, I seriously doubt that this will be your main problem comparing to all you would have to do to get even close to functionality you want to achieve. Delphi applications are full of exception handling (both direct and indirect) on all levels and applications are still running fast. For instance, merely declaring a string variable will insert hidden exception handling code around that string.


  14. 1 hour ago, stacker_liew said:

    It looks like normal for loop is faster than TParallel.For here.

    Yes, because interlocked operation are expensive. Multithreading always comes at a price. The code is more complicated, you need to pay attention to thread safety and it will generally run slower than single threaded code.

     

    Not every operation is worth doing in parallel. If some calculation takes longer time, you can run it in single background thread, so you can keep your application responsive, but for splitting some task to multiple threads, you need to make sure that the task can be successfully parallelized and that performance gained is significant enough. For any operation that runs less than a second, it is usually not even worth to start a single background thread, let alone starting multiple ones.

     

    • Like 1

  15. On 5/6/2023 at 5:40 PM, stacker_liew said:

    I have two program, one is using TParallel, the other is using TTask, both do the same thing, but TParallel  version is far more fast than TTask version, does it true?

    Those two methods you have don't do the same thing. If you take a look to the result of the calculation, you will see that results are different. 

     

    First method will increment sum 1000000 times and second will increment temporary value 1000000 times and then add that temporary result to the total sum 1000 times. So the second method runs more operations and that is why it runs slower.

     

    If you correct the code to calculate exactly the same sum in the second method, you will see that this one will run faster.

     

              for ThreadedI := 0 to Pred(1000) do
              begin
                Inc(ISum);
              end;

     

    Number of tasks running in both cases will be the same, but the second method has the advantage because the temporary calculation is not using interlocked operation which is costly, and only uses it to add that temporary sum to the final result. Overall, Parallel.For code will run interlocked operation 1000000 times, and task based method only 1000 times.

    • Like 3
×