Timing Difference: insert vs. append & reverse | Bytes (2024)

John Keeling

Dear all,
I tried the test program below. My interest is to examine timing
differences between insert vs. append & reverse for a list. My results
on my XP Python 2.3.4 are as follows:
time_reverse 0.889999389648
time_insert 15.7750005722
Over multiple runs ... the time taken to insert at the head of a list,
vs. the time taken to append to a list and then reverse it is
typically 16 or 17 times longer.
I would have expected the insert operation to be faster than the
combined append & reverse operations. Is this behaviour surprising, or
is there a good reason why there is this large performance difference?
Thanks,
John

fromtimeimporttime

deftest():
time_reverse=0.0
time_insert=0.0

forlindxinxrange(100):
tmp1=[]
time_reverse-=time()
forindxinxrange(10000):
tmp1.append(ind x)
tmp1.reverse()
time_reverse+=time()

tmp2=[]
time_insert-=time()
forindxinxrange(10000):
tmp2.insert(0, indx)
time_insert+=time()
asserttmp1==tmp2
print"time_rever se ", time_reverse
print"time_inser t ", time_insert

test()

Jul 18 '05

Subscribe Reply

19 Timing Difference: insert vs. append & reverse | Bytes (1) 11245 Timing Difference: insert vs. append & reverse | Bytes (2)

  • <
  • 1
  • 2

Duncan Booth

br************* **********@yaho o.com (Bryan Olson) wrote in
news:1a******** *************** **@posting.goog le.com:

If you expected insert to be faster, perhaps you thought that Python
used a linked-list implementation. It doesn't do this, because in
practice (for most applications) a [array] based implementation gives
better performance.

True, but an array implementation can easily support amortized
constant-time insert/delete at *either* end (without breaking
constant-time indexing). The same trick of keeping extra space
at the tail end can work at the head; it requires keeping one
additional offset to show where the occupied cells start.

If the OP had said he expected insert and append to be the same speed I
might buy that, but he expected insert to be faster than append.

Jul 18 '05 #11

John Keeling

Clarification.. .

Duncan Booth <du**********@i nvalid.invalid> wrote in message

True, but an array implementation can easily support amortized
constant-time insert/delete at *either* end (without breaking
constant-time indexing). The same trick of keeping extra space
at the tail end can work at the head; it requires keeping one
additional offset to show where the occupied cells start.

If the OP had said he expected insert and append to be the same speed I
might buy that, but he expected insert to be faster than append.

Actually, I never said that ... I said "I would have expected the
insert operation to be faster than the combined append & reverse
operations." The object of my test code was to fill out a list in
the reverse order to which I had the list items available.
I would have expected:
tmp2 =[]
for indx in xrange(10000):
tmp2.insert(0, indx)

to be faster than

tmp1 =[]
for indx in xrange(10000):
tmp1.append(ind x)
tmp1.reverse()

because the insert case does not require the reverse operation. This
would be the case if the insert operated at (approximately) the same
speed as the append, rather then the insert (at position 0) being
16-17 times slower than the append. I guess I somewhat expected it to
be as Bryan Olson stated:"an array implementation can easily support
amortized constant-time insert/delete at *either* end (without
breaking constant-time indexing)."

John

Jul 18 '05 #12

Bryan Olson

Duncan Booth wrote:

Bryan Olson:

[Duncan Booth had written:]

If you expected insert to be faster, perhaps you thought that Python
used a linked-list implementation. It doesn't do this, because in
practice (for most applications) a [array] based implementation gives
better performance.

True, but an array implementation can easily support amortized
constant-time insert/delete at *either* end (without breaking
constant-time indexing). The same trick of keeping extra space
at the tail end can work at the head; it requires keeping one
additional offset to show where the occupied cells start.

If the OP had said he expected insert and append to be the same speed I
might buy that but [...]

Hmmm ... let me clarify what I'm selling: We can make lists
perform efficiently as double-ended queues without breaking
anything or perceptibly hurting anyone's efficiency. Until this
thread, I hadn't realized that Python's lists are much slower
than Perl's in important cases:

http://perlmonks.thepen.com/17890.html
Would this be a PEP-size change, or just a small fix?
--
--Bryan

Jul 18 '05 #13

Tim Peters

[Bryan Olson]

Hmmm ... let me clarify what I'm selling: We can make lists
perform efficiently as double-ended queues without breaking
anything or perceptibly hurting anyone's efficiency. Until this
thread, I hadn't realized that Python's lists are much slower
than Perl's in important cases:

http://perlmonks.thepen.com/17890.html

Would this be a PEP-size change, or just a small fix?

"Futile" is closer -- it's been debated to death repeatedly. Python
2.4 adds a deque type instead, with O(1) insert/remove at both ends,
regardless of access pattern. That's O(1) per operation (not just
amortized O(1) -- the deque type never needs to move entries).

Jul 18 '05 #14

Bryan Olson

Tim Peters wrote:

[Bryan Olson]
[...] I hadn't realized that Python's lists are much slower
than Perl's in important cases:

http://perlmonks.thepen.com/17890.html

Would this be a PEP-size change, or just a small fix?

"Futile" is closer -- it's been debated to death repeatedly. Python
2.4 adds a deque type instead, with O(1) insert/remove at both ends,
regardless of access pattern. That's O(1) per operation (not just
amortized O(1) -- the deque type never needs to move entries).

But it breaks (efficient) indexing. Since we can have it all
like Perl, why not?

Googling up "dequeue" together with "O(1)" in comp.lang.pytho n,
(and with the misspelling "deque" which returns more results) I
see some discussion, but very little reason against the
enhancement. One post by Tim Peters suggests difficulty of
implementation as a major reason.
--
--Bryan

Jul 18 '05 #15

Tim Peters

[Bryan Olson, on complicating the list object again, and 2.4's deque type]

But it breaks (efficient) indexing. Since we can have it all
like Perl, why not?

As I said, the best Perl can do is O(1) amortized. 2.4's deque does
better than that, and that can be important in classes like Python's
Queue.Queue where threads typically block waiting for pops and pushes
(but has no use at all for random access).

If you follow the link you gave last time and read to the bottom
following the other links, you'll find that Perl lists had
quadratic-time behavior under the steady-state queue pattern for a
long time. That was eventually fixed -- or so they say. Small
details are both tricky and vital. 2.4's deque implementation is
obviously immune to "bad" patterns, steady-state queue or otherwise.

Most immediately damning, adding another member to the list struct (to
keep track of the "low bound") would increase the size of every list
object by 8 bytes, on 32-bit boxes. Python lists are easy to spell,
use and access, and some Python apps use millions of small lists.
They wouldn't appreciate the RAM hit for a mostly-useless feature.
Most Perl programmers seem to be so confused by Perl lists that they
only use them when they have to, to shift function arguments in and
out <0.6 wink>. That's a use case for lists Python doesn't have at
all.

You can pursue it if you want to, but with the 2.4 deque type I have
no interest in messing more with the list type.

Jul 18 '05 #16

Bryan Olson

Tim Peters wrote:

[Bryan Olson, on complicating the list object again, and 2.4's dequetype]
But it breaks (efficient) indexing. Since we can have it all
like Perl, why not?

As I said, the best Perl can do is O(1) amortized.

In fact, as both of us said.
If you follow the link you gave last time and read to the bottom
following the other links, you'll find that Perl lists had
quadratic-time behavior under the steady-state queue pattern for a
long time. That was eventually fixed -- or so they say. Small
details are both tricky and vital.
Agreed. But those Perl wizards, misguided as they may be, are
pretty sharp.
2.4's deque implementation is
obviously immune to "bad" patterns, steady-state queue or otherwise.

Most immediately damning, adding another member to the list struct (to
keep track of the "low bound") would increase the size of every list
object by 8 bytes, on 32-bit boxes. Python lists are easy to spell,
use and access, and some Python apps use millions of small lists.
They wouldn't appreciate the RAM hit for a mostly-useless feature.
Most Perl programmers seem to be so confused by Perl lists that they
only use them when they have to, to shift function arguments in and
out <0.6 wink>.
We must know different Perl programmers.
That's a use case for lists Python doesn't have at
all.

You can pursue it if you want to, but with the 2.4 deque type I have
no interest in messing more with the list type.

I'm talking about facilities and their implementations , not
people. True, when I pointed out that Perl nails this one, I
was kinda' thinking the comparison might motivate Pythoners to
pursue the same enhancement. It was certainly *not* meant to
deride anyone who contributed to implementing Python.

Is Tim the superior Pythoner? Duh. Does Python rock? Sure.
Is saving four-or-eight bytes more or less valuable than
providing efficient insert at both ends? With all due respect
to Python and the people who implemented it, Perl kicks on this
one.
--
--Bryan

Jul 18 '05 #17

Tim Peters

[Bryan Olson, on deques & Python's list type]
....

Agreed. But those Perl wizards, misguided as they may be, are
pretty sharp.
Yup.

....

[Tim]

You can pursue it if you want to, but with the 2.4 deque type I have
no interest in messing more with the list type.

[Bryan] I'm talking about facilities and their implementations , not people.
Sure! I'm one of the handful of people who might actually "do
something" about this kind of issue, and I was telling you that I
won't. Your chances of seeing what you suggest are highly correlated
with finding someone who will "do something" <wink>. I don't know
whether Raymond Hettinger is interested in pursuing this further, but
if he isn't either (that's my guess), then the only realistic chance
is if you do the work yourself.
True, when I pointed out that Perl nails this one,
Which part I disagree with, for reasons already given.
I was kinda' thinking the comparison might motivate Pythoners to
pursue the same enhancement.
And the desire for efficient "both ends" operation led to 2.4's deque
type, which isn't "the same" enhancement because it didn't end up in
the base list type, but is a better enhancement for people who truly
need both-ends performance.
It was certainly *not* meant to deride anyone who contributed to implementing
Python.
I didn't read it that way.
Is Tim the superior Pythoner? Duh. Does Python rock? Sure.
Is saving four-or-eight bytes more or less valuable than
providing efficient insert at both ends?
In the basic list type, yes, it's more valuable in Python to save the
8 bytes. The speed of "left end" insert/remove is insignificant for
most Python apps, and is quite fast anyway for small lists. It's a
major concern for *some* Python apps, and the deque type serves those
better than fudging the list type could. The majority who don't care
don't pay for it.
With all due respect to Python and the people who implemented it, Perl kicks
on this one.

I agree that Perl has a good approach here. I think Python's is better, though.

Jul 18 '05 #18

Bryan Olson

Tim Peters wrote:

I'm one of the handful of people who might actually "do
something" about this kind of issue, and I was telling you that I
won't. Your chances of seeing what you suggest are highly correlated
with finding someone who will "do something" <wink>. I don't know
whether Raymond Hettinger is interested in pursuing this further, but
if he isn't either (that's my guess), then the only realistic chance
is if you do the work yourself.
Looking at the source, I'm worried. Append and pop[-1] are not
really amortized O(1); at best they're commonly-average O(1).
Alternating appends and pops at certain border values will call
realloc for every operation. The pop-reallocs free the extra
memory; if the allocator uses that memory for other requests,
the following append will have to copy the entire list.

In the basic list type, yes, it's more valuable in Python to save the
8 bytes. The speed of "left end" insert/remove is insignificant for
most Python apps, and is quite fast anyway for small lists. It's a
major concern for *some* Python apps, and the deque type serves those
better than fudging the list type could.

The leave-it-to-realloc method seems to be an effort to save one
word (either a pointer or a size) per list. With two more
words, I think we could make operations on both ends amortized
O(1). The only lists for which this would be a substantial
portion are empty lists. Currently, empty lists require four
words (type_pointer, refcount, size=0, item_pointer=NU LL) plus
malloc's bookkeeping. Any non-empty list additionally allocates
space for at least 8 pointers, plus malloc's bookkeeping.
--
--Bryan

Jul 18 '05 #19

Tim Peters

[Bryan Olson]

Looking at the source, I'm worried. Append and pop[-1] are not
really amortized O(1); at best they're commonly-average O(1).
Alternating appends and pops at certain border values will call
realloc for every operation. The pop-reallocs free the extra
memory; if the allocator uses that memory for other requests,
the following append will have to copy the entire list.
....
The leave-it-to-realloc method seems to be an effort to save one
word (either a pointer or a size) per list.
What are you looking at? I've been talking about Python 2.4 (as
evidenced by my saying 2.4 over and over <wink>). Its list
implementation is not realloc-happy, and has both allocated-size and
used-size members. The earlier leave-it-to-realloc gimmick was indeed
an extreme effort to save bytes. The 2.4 implementation is simpler,
clearer, faster, and better-behaved in several respects.
With two more words, I think we could make operations on both ends
amortize O(1).
As before, I don't care about this. The 2.4 deque is O(1) on both
ends straightforward ly and more efficiently.
The only lists for which this would be a substantial
portion are empty lists. Currently, empty lists require four
words (type_pointer, refcount, size=0, item_pointer=NU LL)
Plus 3 for the gc header (every list object gets one, although that's
not apparent from staring at listobject.h), plus 1 (not in 2.3 but in
2.4) to store the # of allocated slots. That's a total of 8.
plus malloc's bookkeeping.
The list struct is allocated via pymalloc, which allocates in 8-byte
chunks with trivial overhead beyond that (just a few percent). So not
even 1 bit can be added to the 2.4 list struct without losing another
8 bytes, under *most* C compilers for 32-bit machines. The Microsoft
C compilers are exceptions (they stick 4 bytes of padding in the gc
header, so there are 4 wasted bytes now (2.4) in the list struct under
MSVC).
Any non-empty list additionally allocates space for at least 8 pointers, ...

In 2.4 that's been reduced to 4.

Jul 18 '05 #20

  • <
  • 1
  • 2

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

Similar topics

2 2456

content added to DIV at runtime: timing

by: Timo |last post by:

When content is transferred from a hidden IFRAME (which has fetched data from a database) to a DIV in the main document, how can a script determine that the DIV has been completely populated before it acts upon the data? if (myIFRAME.document.readyState=='complete') myDIV.insertAdjacentHTML("afterBegin",...

Javascript

4 2570

need help with my append syntax

by: yaffa |last post by:

dear folks, i'm trying to append a semicolon to my addr string and am using the syntax below. for some reason the added on of the ; doesn't work. when i print it out later on it only shows the original value of addr. addr = incident.findNextSibling('td') addr.append('%s;') thanks

Python

15 1825

difference /u and

by: Bart |last post by:

Hi, I receive an utf8 character from a database, like 田 (Japanese Character, style: &#XXXXX). How can I visualize the Japanese character on my application? I have found the class System.Text.Encoding, but the input looks like \uXXXX. I don't know how to do. Thank you,

C# / C Sharp

12 2432

by: Tee |last post by:

String Builder & String, what's the difference. and when to use which ? Thanks.

ASP.NET

3 6322

Insert into validation rule violation

by: Bob Alston |last post by:

I have a routine to copy data to new versions of my app via insert into sql statements. Unfortunately, due to evolution of my app, sometimes the new version has more restrictive editing than an older version that I am updating. Thus I get this message. It tells me only how many records have errors, not which errors or which records. ...

Microsoft Access / VBA

2 3282

Timing a function object versus timeit

by: Steven D'Aprano |last post by:

The timeit module is ideal for measuring small code snippets; I want to measure large function objects. Because the timeit module takes the code snippet argument as a string, it is quite handy to use from the command line, but it is less convenient for timing large pieces of code or when working in the interactive interpreter. E.g....

Python

2140

JSP/Dreamweaver Insert Record error

by: ak1dnar |last post by:

There is a Error getting while i am entering records using this jsp file. <%@ page contentType="text/html; charset=iso-8859-1" language="java" import="java.sql.*" errorPage="" %> <%@ include file="../Connections/conn.jsp" %> <% // *** Edit Operations: declare variables // set the form action variable String MM_editAction =...

Java

5 1365

(sort of) deterministic timing in Python

by: John Fisher |last post by:

I am working on a framework for data acquisition in Python 2.5, am trying to get a structure going more like this: mark start time start event event finishes count time until next interval start second event…

Python

1 3750

by: billa856 |last post by:

Hi, I am trying to insert Null value in column(ShipDate) in my table.That column(ShipDate)'s type id date/time and format is short date. I am using "" to insert Null in that column(ShipDate) but it shows warning that customer can't append all the records in the append query. Customer set 1 field(s) to Null due to a type conersion...

Microsoft Access / VBA

7614

Changing the language in Windows 10

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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...

Windows Server

8125

Maximizing Business Potential: The Nexus of Website Design and Digital Marketing

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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...

Online Marketing

1 7676

The easy way to turn off automatic updates for Windows 10/11

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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...

Windows Server

7974

Discussion: How does Zigbee compare with other wireless protocols in smart home applications?

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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...

General

6284

AI Job Threat for Devs

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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...

Career Advice

3653

Trying to create a lan-to-lan vpn between two differents networks

by: TSSRALBI |last post by:

Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...

Networking - Hardware / Configuration

1 2114

transfer the data from one system to another through ip address

by: 6302768590 |last post by:

Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

C# / C Sharp

1 1221

How to add payments to a PHP MySQL app.

by: muto222 |last post by:

How can i add a mobile payment intergratation into php mysql website.

PHP

938

Comprehensive Guide to Website Development in Toronto: Expert Insights from BSMN Consultancy

by: bsmnconsultancy |last post by:

In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

General

Timing Difference: insert vs. append & reverse | Bytes (2024)
Top Articles
Latest Posts
Article information

Author: Sen. Ignacio Ratke

Last Updated:

Views: 6273

Rating: 4.6 / 5 (56 voted)

Reviews: 87% of readers found this page helpful

Author information

Name: Sen. Ignacio Ratke

Birthday: 1999-05-27

Address: Apt. 171 8116 Bailey Via, Roberthaven, GA 58289

Phone: +2585395768220

Job: Lead Liaison

Hobby: Lockpicking, LARPing, Lego building, Lapidary, Macrame, Book restoration, Bodybuilding

Introduction: My name is Sen. Ignacio Ratke, I am a adventurous, zealous, outstanding, agreeable, precious, excited, gifted person who loves writing and wants to share my knowledge and understanding with you.