I've run small size tests which consistently show that using query()/execute() is 4 times faster than using any of queuing functions even when I set *client._QUERIES_QUEUE_CHECK_INTERVAL = 1* ms.
- execute() for 5000 records is completed in 16 seconds consistently.
- queuing via addNonQuery() is completed in 78 seconds consistently.
This leads to 4.8 times difference.
*Is it really all that can be done for queuing?*
Here are my observations:
1. As I can see from the code, we run the next query in the queue every *_QUERIES_QUEUE_CHECK_INTERVAL*. Why is this necessary?
2. *_enableQueriesBackgroundProcessor()* is a watch dog which monitors the queue. Why do we need to check every time whether or not the query is finished running?
3. For this reason *_enableQueriesBackgroundProcessor()* itself is O(2N).
4. *_executeQuery()* executes the query based on its type. When the current query is completed, the function removes the query from the queue.
The current implementation is quite inefficient. Here are some thoughts to improve it. If you have already thought about them and found problems with them, let me know.
1. When a user runs *addQuery()/addNonQuery()*, they will enqueue the query to a queue. If and only if the query has only 1 item, i.e. the current item, then start *_executeQuery()*.
2. *_executeQuery()* will *not pop* but reference the *first* query and execute it.
3. When completed executing the query (both query and non-query) without an error, pop it out of the queue.
4. Check if there is anything more in the queue. Jump to 2 again if there is a query in the queue to execute.
5. If queue is empty, do nothing.
This way:
1. There is no need for interval check.
2. No need to keep looping through the queue checking if the query is completed executing.
2. We don't lose the precious milliseconds waiting for settimeout to fire.
3. The queries will be executed as soon as previous query is completed running.
This technique can theoretically lead to almost the same performance as running without a queue.