473,405 Members | 2,176 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

Popping from the middle of a deque + deque rotation speed

Does anyone have an easier/faster/better way of popping from the middle
of a deque than this?

class mydeque(deque):
def popmiddle(self, pos):
self.rotate(-pos)
ret = self.popleft()
self.rotate(pos)
return ret

I do recognize that this is not the intent of a deque, given the
clearly non-"double-ended" nature. I'm using a deque in a place where
99.999 of the time it will be a fifo, but occasionally I will want to
pop from the middle.

I initially wrote that thinking that the rotate duration would be
independent of the rotation distance, but...
import timeit
s = "from collections import deque; d = deque(xrange(1000000))"
timeit.Timer(stmt="d.rotate(1)", setup = s).timeit(number=100000) 0.1372316872675583 timeit.Timer(stmt="d.rotate(1000)", setup = s).timeit(number=100000) 3.5050192133357996 timeit.Timer(stmt="d.rotate(10000)", setup = s).timeit(number=100000) 32.756590851630563 timeit.Timer(stmt="d.rotate(100000)", setup = s).timeit(number=100000) 325.59845064107299 timeit.Timer(stmt="d.rotate(999999)", setup = s).timeit(number=100000)

0.14491059617921564

Boy was I wrong. Given that it scales linearly it looks like it
cut-pastes the rotation an element at a time! At least it recognizes
the shortest rotation path, though.

On first guess of how the deque is implemented I would have thought
that rotation could be achieved simply by diddling some pointers, but I
could see how that would mess with popping efficiency (seems you'd have
to remap memory in the event of a pop after rotation). Worst case I
figured a rotate would just do a single shot memory remapping of the
deque contents so that the speed was the same regardless of rotation
size...

My guessing/figuring skills clearly need some work.

What's up with this deque rotation? If I were to hazard one more guess
I'd think it is trying to conserve transient memory usage during
rotation... in my (poor) mental scheme it seems that cutting/relocating
could take 50% more memory than the deque itself for a full rotation.

I should stop guessing. Or at least figure out how to find the source
code for the deque implementation...

Should I avoid using deques with large iterables?

Thanks,
Russ

Apr 28 '06 #1
5 3486
> Does anyone have an easier/faster/better way of popping from the middle
of a deque than this?

class mydeque(deque):
def popmiddle(self, pos):
self.rotate(-pos)
ret = self.popleft()
self.rotate(pos)
return ret


My first thought would just be to use indexing:

def popmiddle(self, pos):
ret = self[pos]
del(self[pos])
return ret

It seems to work with my Python2.4 here. If you're
interested in efficiency, I'll leave their comparison as an
exercise to the reader... :)

-tkc

Apr 28 '06 #2
[Russell Warren]
|> Does anyone have an easier/faster/better way of popping from the middle
of a deque than this?

class mydeque(deque):
def popmiddle(self, pos):
self.rotate(-pos)
ret = self.popleft()
self.rotate(pos)
return ret
As Tim Chase said, the easiest way is to do "del self[pos]" instead of
manually fiddling with rotations. However, deque's implementation of
__delitem__ does rotations under the covers, so it's not necessarily
faster.
I do recognize that this is not the intent of a deque, given the
clearly non-"double-ended" nature. I'm using a deque in a place where
99.999 of the time it will be a fifo, but occasionally I will want to
pop from the middle.
So does the speed of the remaining 0.001 cases really matter? Note
that even just indexing into a deque takes O(index) time.
...
I should stop guessing. Or at least figure out how to find the source
code for the deque implementation...
It's in Modules/collectionsmodule.c. You'll see that a deque is
implemented as a doubly-linked list of buckets, where each bucket is a
contiguous vector of no more than 62 (pointers to) elements. There
appears to be an invariant that all "interior" (non-endpoint) buckets
contain exactly 62 elements, presumably to speed indexing. It all
works very well for deque's intended purposes.
Should I avoid using deques with large iterables?


Can't answer that without more detail about the criteria you use to judge ;-)
Apr 29 '06 #3
Thanks for the responses.
It seems to work with my Python2.4 here. If you're
interested in efficiency, I'll leave their comparison as an
exercise to the reader... :)


Ok, exercise complete! :) For the record, they are pretty much the
same speed...
s = """ .... from collections import deque
.... class mydeque(deque):
.... def popmiddle(self, pos):
.... self.rotate(-pos)
.... ret=self.popleft()
.... self.rotate(pos)
.... return ret
.... d = mydeque(xrange(1000000)) timeit.Timer(stmt="x=d.popmiddle(1000)", setup = s).timeit(number=100000) 5.4620059253340969 s2=""" .... from collections import deque
.... class mydeque(deque):
.... def popmiddle(self, pos):
.... ret = self[pos]
.... del(self[pos])
.... return ret
.... d = mydeque(xrange(1000000))
.... """ timeit.Timer(stmt="x=d.popmiddle(1000)", setup = s2).timeit(number=100000)

5.3937888754018104

Thanks for the alternative solution.

Russ

May 1 '06 #4
> So does the speed of the remaining 0.001 cases really matter? Note
that even just indexing into a deque takes O(index) time.


It doesn't matter as much, of course, but I was looking to make every
step as efficient as possible (while staying in python).

As to indexing into a deque being O(index)... I didn't realize that.
It is certainly something to keep in mind, though... looping through
the contents of a deque would obviously be a bad idea with this being
the case! I wonder if the generator for the deque helps reduce this?
Will check later.

Proof of the O(n) for indexing into a deque (not that I doubted Tim #2!
:)...
import timeit
s = "from collections import deque; d = deque(xrange(1000000))"
timeit.Timer(stmt="x=d[10000]", setup = s).timeit(number=100000) 0.14770257113683627 timeit.Timer(stmt="x=d[100000]", setup = s).timeit(number=100000)

1.4016418287799155

Russ

May 2 '06 #5
[Russell Warren]
...
As to indexing into a deque being O(index)... I didn't realize that.
It is certainly something to keep in mind, though... looping through
the contents of a deque would obviously be a bad idea with this being
the case! I wonder if the generator for the deque helps reduce this?
Will check later.


FYI, deque implements efficient forward and reverse iterators. So, e.g.,

for x in a_deque:
pass

and

for x in reversed(a_deque):
pass

takes time proportional to len(a_deque). In contrast,

for i in xrange(len(a_deque)):
x = a_deque[i]

take time quadratic in len(a_deque).

The iterators don't use __getitem__ under the covers; explicitly
indexing does, and that's the difference here.
May 2 '06 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

21
by: M. Clift | last post by:
Hi All, Could someone help me out with this? items = ('a', 'b', 'c', 'd') items + 1 = ( 'b', 'c', 'd', 'a') items + 2 = ( 'c', 'd', 'a', 'b') items + 3 = ( 'd', 'a', 'b', 'c') trans = 1
16
by: newsock | last post by:
What differences between queue, deque and priority_queue? And under what situations choose one of them to use? Thanks for your help!
7
by: Jenny | last post by:
Hi, I have a class foo which will construct some objects in my code. some of the objects store int values into the data deque, while others store float values to the deque. template <class...
3
by: Gernot Frisch | last post by:
Hi, which container class can I use that has push/pop at front/back and allows me to remove any object in the queue? -- -Gernot int main(int argc, char** argv) {printf...
9
by: R.Z. | last post by:
i was wondering whether it pays off in terms of memory use to maintain lots of empty deques (it would be convenient for my algorithms but memory use is more important). and does the size of a deque...
5
by: yancheng.cheok | last post by:
after reading http://www.codeproject.com/vcpp/stl/vector_vs_deque.asp, i realize that deque has its own speed advantage over vector in all the aspect (except for memory deallocation). does it...
1
by: Homeworkboy | last post by:
Can anyone help me with this program? Look at the bottom of this program for help methods: /*1. Make a program that uses numbers from 1 to 100 including each ends which puts the even...
15
by: Juha Nieminen | last post by:
I'm sure this is not a new idea, but I have never heard about it before. I'm wondering if this could work: Assume that you have a common base class and a bunch of classes derived from it, and...
29
by: NvrBst | last post by:
I've read a bit online seeing that two writes are not safe, which I understand, but would 1 thread push()'ing and 1 thread pop()'ing be thread-safe? Basically my situation is the follows: ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.