473,471 Members | 2,613 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Need an identity operator because lambda is too slow

This is an optimization problem, one that occurs deep inside a loop
that gets executed thousands of times. I'm looking for something in
Python which would act like an identity operator, or I-combinator: a
do-nothing function. The best I know of is: (lambda x: x), but it is
not ideal.

Consider a much-simplified example of such an iteration where
sometimes you need to transform an item by some function, but most of
the time you don't:

if some_rare_condition:
func = some_transform_function
else:
func = lambda x: x
for item in some_sequence:
item2 = func(item)
..... # more stuff

Now the "lambda x:x" acts suitably like an identity operator. But it
is very slow, when compared to using more complex-looking code:

do_transform = some_rare_condition
for item in some_sequence:
if do_transform:
item2 = transform_function(item)
else:
item2 = item
..... # more stuff

What python needs is something like a built-in "operator.identity"
function, which acts like "lambda x:x", but which the byte compiler
could recognize and completely optimize away so there is no function
call overhead.

Does this exist someplace in the corners of the language, or are there
any ideas about how best to do something like this without having to
push a bunch of ugly if-then-else constructs inside all the loops
rather than a more elegant function object? (The need for this is
more obvious in my real-world code versus the simplified examples
above).

Thanks
--
Deron Meranda

Feb 18 '07 #1
7 2395
"Deron Meranda" <de***********@gmail.comwrites:
do_transform = some_rare_condition
for item in some_sequence:
if do_transform:
item2 = transform_function(item)
else:
item2 = item
..... # more stuff
This might be a little more direct:

from itertools import imap
if some_rare_condition:
mapped_sequence = imap(transform_function, some_sequence)
else:
mapped_sequence = some_sequence

for item in mapped_sequence:
# more stuff

I agree that an identity function would be useful. I think I
suggested it a long time ago and didn't get much interest.
Feb 18 '07 #2
[Deron Meranda
>] I'm looking for something in
Python which would act like an identity operator, or I-combinator: a
do-nothing function. The best I know of is: (lambda x: x), but it is
not ideal.
File a feature request on SourceForge and assign to me. This has come
up a couple of times and would be trivial to implement in the operator
or functools modules.

Raymond

Feb 18 '07 #3
On Sat, 17 Feb 2007 21:59:18 -0800, Deron Meranda wrote:
Consider a much-simplified example of such an iteration where
sometimes you need to transform an item by some function, but most of
the time you don't:

if some_rare_condition:
func = some_transform_function
else:
func = lambda x: x
for item in some_sequence:
item2 = func(item)
..... # more stuff
This does the test once, but does a function look-up every loop.

Now the "lambda x:x" acts suitably like an identity operator. But it
is very slow, when compared to using more complex-looking code:

do_transform = some_rare_condition
for item in some_sequence:
if do_transform:
item2 = transform_function(item)
else:
item2 = item
..... # more stuff
Despite doing the if..else comparison every loop, this is a little faster
for the case where some_rare_condition is false.

But I have to question whether this is a worthwhile optimization,
especially if some_rare_condition really is rare. Calling the identity
function "lambda x: x" one million times takes about half a second; or to
put it another way, each call to the identity function costs you about
half a microsecond. How much time does the rest of the loop processing
take? Are you sure you're optimizing something which needs to be optimized?

(E.g. if your main loop takes fifteen minutes to run, and you're trying to
shave off half a second, just don't bother.)

Compare the following, where I use an arbitrary small function as a
placeholder for whatever work you really want to do:

setup = """import time
identity = lambda x: x
do_work = lambda x: time.time() + x
x = 1
"""

Now use timeit to compare doing the work on its own with doing the work
together with an identity function:
>>timeit.Timer("do_work(x)", setup).repeat()
[3.1834621429443359, 3.1083459854125977, 3.1382210254669189]
>>timeit.Timer("do_work(identity(x))", setup).repeat()
[3.5951459407806396, 3.6067559719085693, 3.5801000595092773]

Is your "do_work" function really so fast that one second per two million
calls to identity() is a significant load?

If some_rare_condition really is rare, then a possible solution might
be:

if some_rare_condition:
some_sequence = [transform(item) for item in some_sequence]
# or modify in place if needed... see enumerate
for item in some_sequence:
do_something_with(item)

This should run as fast as possible in the common case, and slow down only
in the rare condition.

Another solution would be:

if some_rare_condition:
for item in some_sequence:
item = transform(item)
do_something_with(item)
else:
for item in some_sequence:
do_something_with(item)

This is probably going to be the fastest of all, but has the disadvantage
that you are writing the same code twice.


--
Steven.

Feb 18 '07 #4
On Sat, 17 Feb 2007 22:19:41 -0800, Raymond Hettinger wrote:
[Deron Meranda
>>] I'm looking for something in
Python which would act like an identity operator, or I-combinator: a
do-nothing function. The best I know of is: (lambda x: x), but it is
not ideal.

File a feature request on SourceForge and assign to me. This has come
up a couple of times and would be trivial to implement in the operator
or functools modules.
I'm surprised. The Original Poster specified

[quote]
What python needs is something like a built-in "operator.identity"
function, which acts like "lambda x:x", but which the byte compiler
could recognize and completely optimize away so there is no function
call overhead.
[end quote]

I would have guessed that optimizing the call away would require support
from the compiler.

--
Steven.

Feb 18 '07 #5
On Feb 18, 5:59 am, "Deron Meranda" <deron.mera...@gmail.comwrote:
Consider a much-simplified example of such an iteration where
sometimes you need to transform an item by some function, but most of
the time you don't:

if some_rare_condition:
func = some_transform_function
else:
func = lambda x: x
for item in some_sequence:
item2 = func(item)
..... # more stuff

Now the "lambda x:x" acts suitably like an identity operator. But it
is very slow, when compared to using more complex-looking code:

do_transform = some_rare_condition
for item in some_sequence:
if do_transform:
item2 = transform_function(item)
else:
item2 = item
..... # more stuff

What python needs is something like a built-in "operator.identity"
function, which acts like "lambda x:x", but which the byte compiler
could recognize and completely optimize away so there is no function
call overhead.
Unless I'm misunderstanding you, you seem to be proposing that the
compiler should avoid generating the call to func2() if it has a
certain value. How could that information possibly be available at
compile time?

-- David

Feb 18 '07 #6
On Feb 17, 9:59 pm, "Deron Meranda" <deron.mera...@gmail.comwrote:
[snip]

this may be really dense, but i'm curious what's wrong with the
"multiplexer" idiom:

for item in some_sequence:
item2 = (not some_rare_condition and item) or \
(some_rare_condition and
some_transform_function(item))
..... # more stuff

peace
stm

Feb 19 '07 #7
En Sun, 18 Feb 2007 23:31:53 -0300, Sean McIlroy <se**********@yahoo.com>
escribió:
On Feb 17, 9:59 pm, "Deron Meranda" <deron.mera...@gmail.comwrote:
[snip]

this may be really dense, but i'm curious what's wrong with the
"multiplexer" idiom:

for item in some_sequence:
item2 = (not some_rare_condition and item) or \
(some_rare_condition and
some_transform_function(item))
..... # more stuff
The main concern of the OP was that lambda x:x is slow, so it's better to
move the condition out of the loop.
Also, this and/or trick does not work when the Boolean value of item is
false (like 0, (), []...)

--
Gabriel Genellina

Feb 19 '07 #8

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

Similar topics

181
by: Tom Anderson | last post by:
Comrades, During our current discussion of the fate of functional constructs in python, someone brought up Guido's bull on the matter: http://www.artima.com/weblogs/viewpost.jsp?thread=98196 ...
9
by: Rathtap | last post by:
I want to use the Identity field (increment 1,1) as a primary key and have a unique constraint on my other field which is of type char. I am worried that related data in other tables may lose...
48
by: Daniel Crespo | last post by:
Hi! I would like to know how can I do the PHP ternary operator/statement (... ? ... : ...) in Python... I want to something like: a = {'Huge': (quantity>90) ? True : False} Any...
3
by: Dsquare | last post by:
CREATE PROCEDURE sp_InsertMaterial @MatEngName nvarchar(100),@MatJapName nvarchar(500),@Comments nvarchar(500),@ImagePath nvarchar(100),@ImageStatus nvarchar(50),@AddedDate datetime AS ...
37
by: spam.noam | last post by:
Hello, Guido has decided, in python-dev, that in Py3K the id-based order comparisons will be dropped. This means that, for example, "{} < " will raise a TypeError instead of the current...
8
by: shenanwei | last post by:
I have 2 same windows machine, same instance configure and Database , all run DB2 UDB V8.1.5 Test 1 : create table OUT_1 (LINE VARCHAR(350), LINENUMBER INTEGER NOT NULL GENERATED ALWAYS AS...
2
by: James Stroud | last post by:
Hello all, What /is/ identity in python? For example, we can always count on py> None is None True But I have noticed that this works for strings: py> "none" is "none"
6
by: =?iso-8859-1?q?Erik_Wikstr=F6m?= | last post by:
Is there some way to get a function-pointer to the operators of the builtin types? In the following example I have a generic function which applies an operator on two values, however it does not...
1
by: ruchirp | last post by:
Hi, I've been trying to overload << for a function similar to boost lambda library. I want to make for_each(v.begin(), b.end(), cout << _1 << endl); to work, however, i'm getting a lot of problems...
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
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
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
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
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...
1
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
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...
0
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.