Jump to content

snowdev

Members
  • Content Count

    3
  • Joined

  • Last visited

Community Reputation

0 Neutral
  1. Its a bit weird. I also running in debug and didnt got leaks. Ya, I forgot the correct term. Anyway I already planning some changes: -Change TCriticalSection locking for TLightweigtMREW gabr42 version (discussion here: https://www.thedelphigeek.com/2021/02/readers-writ-47358-48721-45511-46172.html?m=1) Another change would be: -Switch from single worker thread processing to N worker thread processing: I have a worker that loops an array and do what is necessary based on the item settings, so the thread retrieve the data every notification from this array… Instead I’ll create a threadpool like (or a simple TThread list) and pre-creates the worker threads with the pre-defined parameters, then I’ll just signaling they when necessary, the necessary information already be there. Final probably change: -Switch from TQueue to ring buffer like. Thanks for educate me. The external API which I consume returns PWideChar and is a pain to work in certain circumstances… I’ll evaluate change to array of char. Thanks again Anders.
  2. I’ve search over the internet when I started the project and found some posts around TMonitor performance. I also found a gabr42’s (OmniThreadLibrary creator) blog post about this and just decided to use TCriticalSection. Thats make sense, I’ve tested this way and got similar results, and the simple fifo queue wons (working with objects or pointers). Not exactly, using ReportMemoryLeaksOnShutdown didnt take any leak running the tests… every queue format release their resources. I’ll take a look into that, usually dont. This reason I dont included in the given example… every thread became up on the app initialization. Thanks for the tip. I dont know a profiling lib for Delphi, but I’ll measure them with stopwatches. I just use locking because I dont know if there could have a deadlock when other thread is pushing and the worker is popping, so I do it just in case. You say that this scenario isnt that possible? About Windows message queue, it seems slow as a simple fifo aswell, thought continue using this approach. In the next few days I’ll build a ring buffer like approach and test the performance compared to TQueue, it internal uses an array of T btw. About strings I could switch to PWideChar aswell, I use string for ease. Almost same performance as TQueue. Thanks for the reply.
  3. I have an application which continuously receives websocket data and proccess them in the background on worker threads. Some data is critical and must be proccessed as quickly as possible. Once I receive the websocket data I fill a TObject descendent with the information and push it to the corresponding worker thread, which proccess and frees the object. I use Delphi 12. I would like to reduce as much overhead as possible in the flow, and beside the business rules, I believe there is an overhead in my worker thread consumer implementation, especially because I work with TObject descendants to transport the data. Also there has TObject cloning when the communication occurs from worker thread to worker thread, because each worker thread owns the queue objects lifetime, so I need to send a copy for each worker thread. I decided to make a benchmark to check by myself the differente in the differet approachs that I know about threading queues and know what has the best performance, attached has the benchmark I build. Nowdays I use CustomQueueObject.pas queue model in prod. In the example, has 4 examples of threading consumer queues: -A thread with TQueue<TObject>, TSempahore and TCritical Section; -A thread with TQueue<Pointer>, TSempahore and TCritical Section; -A thread with internal TThread queue processing TObject descendents, without events and sync objects; -A thread with internal TThread queue processing Pointers, without events and sync objects; After making tons of tests, for my surprise the fastest consumer queue is the example in CustomQueueObject.pas (which I already use), even with more creation/deletion and access control (sync object)... what brought me here to ask more experienced developers if I doing something wrong (according my examples as is my base). Mainly on Pointer examples as I rarely use pointers but I willing to change if its better. In my mind the internal thread queue would much more efficient for the reasons said above... I also thought that work with Pointers could highly improve the overal performance as in the workflow since I would have a single reference and only freed in the final. Could I be measuring the performance incorrectly? Thanks in advance! MultithreadingQueueBenchmark.zip
×