From: "byroot (Jean Boussier) via ruby-core" Date: 2025-12-13T07:10:27+00:00 Subject: [ruby-core:124177] [Ruby Feature#21721] Allow `Queue` and `SizedQueue` to be used as LIFO queues Issue #21721 has been updated by byroot (Jean Boussier). So, if Monitor was made a core class, it could benefit from some optimizations and be almost as fast as Mutex: https://github.com/ruby/ruby/pull/15538 ``` ruby 4.0.0dev (2025-12-13T06:49:18Z core-monitor 6fabf389fd) +YJIT +PRISM [arm64-darwin25] Warming up -------------------------------------- Mutex 2.144M i/100ms Monitor 1.859M i/100ms Calculating ------------------------------------- Mutex 24.771M (� 0.4%) i/s (40.37 ns/i) - 124.342M in 5.019716s Monitor 23.722M (� 0.4%) i/s (42.15 ns/i) - 118.998M in 5.016361s ``` ``` ruby 4.0.0dev (2025-12-13T06:49:18Z core-monitor 6fabf389fd) +YJIT +PRISM [arm64-darwin25] Warming up -------------------------------------- core-queue 1.376M i/100ms ar-queue 752.179k i/100ms cp gem 256.479k i/100ms Calculating ------------------------------------- core-queue 16.177M (� 0.4%) i/s (61.82 ns/i) - 81.164M in 5.017453s ar-queue 9.008M (� 0.1%) i/s (111.02 ns/i) - 45.131M in 5.010316s cp gem 2.547M (� 0.8%) i/s (392.60 ns/i) - 12.824M in 5.035096s Comparison: core-queue: 16176630.9 i/s ar-queue: 9007570.8 i/s - 1.80x slower cp gem: 2547095.9 i/s - 6.35x slower ``` ``` ---------------------------------------- Feature #21721: Allow `Queue` and `SizedQueue` to be used as LIFO queues https://bugs.ruby-lang.org/issues/21721#change-115648 * Author: byroot (Jean Boussier) * Status: Open ---------------------------------------- ### Context Since `Queue` and `SizedQueue` gained a proper timeout mechanism, I've been wanting to use them to implement simpler and more efficient connection pools. However for connection pools you ideally want a LIFO queue because it's preferable to checkout the most recently used connection. ### Problem Both `Queue` and `SizedQueue` only support FIFO because you can only enqueue elements at the beginning of the backing array, and only dequeue at the end. `Queue#push` (aliased as `Queue#<<` and `Queue#enq`) calls `Array#unshift` on the backing array and `Queue#pop` (aliased as `Queue#deq` and `Queue#shift`) calls `Array#pop`. Hence it is impossible to use these two classes for anything other than FIFO queues. I tried to use `git blame` to see if there was a justification for this, but I ended up in a git blame loop around May 2000 https://github.com/ruby/ruby/commit/9da4f78db46764be6dae5e7e83ff48cbecb3fb23 ### Feature I'd like to introduce either of two new methods (or both) to allow for LIFO: - A method to dequeue from the beginning of the backing array (`array_shift`). - A method to enqueue from the end of the backing array (`array_push`). A difficulty I have however is that since the common `shift/pop/push` terms are already used with uncommon meaning, it's hard to come up with good names. Ideas welcome. ### Possible alternatives - Define different classes for LIFO queues - But I find that less flexible, and it means exposing new constant names in the global namespace. - Add an initializer argument to define the queue ordering, e.g. `Queue.new([], lifo: true)` - Similarly, I find this less flexible than to decide the order during enqueue/dequeue - Add an argument to `Queue#pop` and `Queue#push`, e.g. `queue.push(element, front: true)`. -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/