From a2650262b0c2523a01ddc5ce492fdc24c7348cda Mon Sep 17 00:00:00 2001 From: Viknashvaran Narayanasamy Date: Wed, 8 Jul 2026 09:06:39 +0800 Subject: [PATCH] perf: remove virtual dispatch from lock_free_queue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All lock_free_queue methods (push_back, pop_front, pop_back, empty) were declared virtual, but every queue object is accessed through its concrete type — vtable dispatch was pure overhead on the hot path. Changes: - Remove `virtual` from all lock_free_queue methods; destructor becomes `= default` (no polymorphic deletion needed) - Remove task_queue_type::push_back override that only forwarded to super::push_back — now inherits the base implementation directly - Remove the now-unused `super` typedef and virtual destructor from task_queue_type This eliminates one indirect branch and one vtable pointer (8 bytes) per queue instance on every push/pop/empty call in the scheduler loop. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- include/lockfreequeue.h | 12 ++++++------ include/taskgraph.h | 9 --------- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/include/lockfreequeue.h b/include/lockfreequeue.h index 48da772..78ae6dc 100644 --- a/include/lockfreequeue.h +++ b/include/lockfreequeue.h @@ -242,17 +242,17 @@ namespace task_scheduler { { } - virtual bool push_back(T newData) { return queue.push_back(newData); } + bool push_back(T newData) { return queue.push_back(newData); } - //virtual bool push_front(T newData) { return queue.push_front(newData); } + //bool push_front(T newData) { return queue.push_front(newData); } - virtual bool pop_front(T &val) { return queue.pop_front(val); } + bool pop_front(T &val) { return queue.pop_front(val); } - virtual bool pop_back(T &val) { return queue.pop_front(val); } + bool pop_back(T &val) { return queue.pop_front(val); } - virtual bool empty() const { return queue.empty(); } + bool empty() const { return queue.empty(); } - virtual ~lock_free_queue() {} + ~lock_free_queue() = default; TPolicy queue; }; diff --git a/include/taskgraph.h b/include/taskgraph.h index 7865472..c5b0d91 100644 --- a/include/taskgraph.h +++ b/include/taskgraph.h @@ -78,11 +78,8 @@ namespace task_scheduler class task_queue_type : public base_task_queue_type { - typedef base_task_queue_type super; public: task_queue_type(task_memory_allocator_type *allocator); - bool push_back(typename base_task< TMemInterface >::task_type * _new_task); - virtual ~task_queue_type() {} }; /// @@ -291,12 +288,6 @@ namespace task_scheduler { } - template < class TMemInterface > - bool base_task_graph< TMemInterface >::task_queue_type::push_back(typename base_task< TMemInterface >::task_type * _new_task) - { - return super::push_back(_new_task); - } - template < class TMemInterface > base_task_graph< TMemInterface >::base_task_graph(thread_pool &_pool) : transient(&task_memory_allocator)