Mutable numbers

S

Suresh Jeevanandam

# I am new to python.

In python all numbers are immutable. This means there is one object ( a
region in the memory ) created every time we do an numeric operation. I
hope there should have been some good reasons why it was designed this way.

But why not have mutable numbers also in the language. A type which
would behave as follows:

a = MutableInt(12)
b = a

Now both a and b should refer to the same memory location. Any change in
the object should get reflected in all the references.

a.assign(13) # Same memory location should be updated with value 13, b
is also 13 now.

Now we can further optimize:

a.incrementOne() # equivalent to a++ in C++
a.decrementOne()

and the augmented assignment operation also could be made optimized.

In any application most of the operation is numerical. So, i think, we
should get a good speed advantage with the availability of mutable
numbers. What do you think ?

regards,
Suresh
 
E

Erik Max Francis

Suresh said:
But why not have mutable numbers also in the language.

The short answer I'd give is probably that this is so easy to do with a
user-defined class that it's never been all that pressing.
In any application most of the operation is numerical. So, i think, we
should get a good speed advantage with the availability of mutable
numbers. What do you think ?

Why do you think this would afford any speed advantage at all? The
reason that math operations are potential slow in Python is because it's
interpreted; having mutable numerics doesn't change that fact.
 
G

Giovanni Bajo

Suresh said:
In python all numbers are immutable.
True.

This means there is one object (
a region in the memory ) created every time we do an numeric
operation.

False. Memory regions can be pooled in a way that "allocation" is a O(1)
operation.
I hope there should have been some good reasons why it was
designed this way.

Yes, so that you can obtain a pass-by-value semantic for numeric types. That
is, if you pass a number to a function, it can't modify it. You consistenly use
"a = foo(a)" to do a calculation on "a", instead of having half programs doing
"foo(a)" and the other half doing "a = foo(a)". Also, it's done so that you
don't need to special case integer literals: they are (fixed) names to the same
immutable instances and nobody can modify the value of 13 or any other literal.
But why not have mutable numbers also in the language. A type which
would behave as follows:

a = MutableInt(12)
b = a

Now both a and b should refer to the same memory location. Any change
in the object should get reflected in all the references.

a.assign(13) # Same memory location should be updated with value 13, b
is also 13 now.

Now we can further optimize:

a.incrementOne() # equivalent to a++ in C++
a.decrementOne()

and the augmented assignment operation also could be made optimized.

So you just created a numeric type which does not work with normal operators.
This is so unpythonic. I don't think anybody wants to write "incrementOne" when
"+ 1" exists and does the same it used to do in primary school. Even if you
overloaded all the operators, you still wouldn't be able to use '=' to do
assignment, which pretty much makes your class useless or very unpythonic to
use (= wrong).
In any application most of the operation is numerical. So, i think, we
should get a good speed advantage with the availability of mutable
numbers. What do you think ?


You are doing premature optimization. It's so premature that it's even a brain
thing. You *presume* Python to be slow, you *presume* that this presumed
slowness comes from numbers being immutables. But you didn't *measure* it, you
didn't try it on a real-world case. You didn't even look at the Python source
code to check if your assumptions were true. Try to check your assumptions
before designing solutions to problems which do not exist. I suggest you start
writing real-world Python before doing so many assumptions.
 
F

fraca7

Suresh Jeevanandam a écrit :
# I am new to python.

In python all numbers are immutable. This means there is one object ( a
region in the memory ) created every time we do an numeric operation. I
hope there should have been some good reasons why it was designed this way.

The memory allocation for integers is optimized. 'Small' integers
(between -5 and 100 IIRC) are allocated once and reused. The memory for
larger integers is allocated once and reused whenever possible, so the
malloc() overhead is negligible.
 
S

Steve Holden

fraca7 said:
Suresh Jeevanandam a écrit :



The memory allocation for integers is optimized. 'Small' integers
(between -5 and 100 IIRC) are allocated once and reused. The memory for
larger integers is allocated once and reused whenever possible, so the
malloc() overhead is negligible.

The first bit's right, the second bit isn't:

regards
Steve
 
S

Steve Holden

fraca7 said:
Suresh Jeevanandam a écrit :



The memory allocation for integers is optimized. 'Small' integers
(between -5 and 100 IIRC) are allocated once and reused. The memory for
larger integers is allocated once and reused whenever possible, so the
malloc() overhead is negligible.

[Thinks: or maybe fraca7 just meant that integers will be garbage
collected when there are no more references to them].

regards
Steve
 
F

Fredrik Lundh

Steve said:
The first bit's right, the second bit isn't:

quoting from Objects/intobject.c :

Integers are quite normal objects, to make object handling uniform.
(Using odd pointers to represent integers would save much space
but require extra checks for this special case throughout the code.)
Since a typical Python program spends much of its time allocating
and deallocating integers, these operations should be very fast.
Therefore we use a dedicated allocation scheme with a much lower
overhead (in space and time) than straight malloc(): a simple
dedicated free list, filled when necessary with memory from malloc().

http://svn.python.org/projects/python/trunk/Objects/intobject.c

</F>
 
D

Dave Hansen

# I am new to python.

In python all numbers are immutable. This means there is one object ( a
region in the memory ) created every time we do an numeric operation. I
hope there should have been some good reasons why it was designed this way.

But why not have mutable numbers also in the language. A type which
would behave as follows:

a = MutableInt(12)

a = [12]
b = a

Now both a and b should refer to the same memory location. Any change in
the object should get reflected in all the references.

a.assign(13) # Same memory location should be updated with value 13, b

a[0] = 13
is also 13 now.

Now we can further optimize:

a.incrementOne() # equivalent to a++ in C++
a.decrementOne()

a[0] += 1
a[0] -= 1
and the augmented assignment operation also could be made optimized.

In any application most of the operation is numerical. So, i think, we
should get a good speed advantage with the availability of mutable
numbers. What do you think ?

I don't see how.

HTH,
-=Dave
 
F

fraca7

Steve Holden a écrit :
[Thinks: or maybe fraca7 just meant that integers will be garbage
collected when there are no more references to them].

Actually I meant that the memory is reused, but the same integer won't
always have the same address.

I guess that in your example, the '121' is assigned the 'old' address of
12100, and the result of the operation is assigned the next chunk; the
following seems to confirm that:
8628480
 
F

fraca7

fraca7 a écrit :
Steve Holden a écrit :
[Thinks: or maybe fraca7 just meant that integers will be garbage
collected when there are no more references to them].

Actually I meant that the memory is reused, but the same integer won't
always have the same address.

And of course this means they're garbaged collected, but free() won't be
called. I must read before answering :)
 
R

Rocco Moretti

Steve said:
The first bit's right, the second bit isn't:

FWIW, I read "whenever possible" not as "whenever theoretically
possible" but as "whenever the (comparatively simple) interpreter
recognizes that reuse is possible".
a = 12100
b = 12100
c = 121*100
print a is b
print a is c

True
False

The interpreter, when compiling the function, can recognize that the two
constants are identical, and makes them the same object. On the
interactive interpreter, or after a computation, the interpreter doesn't
bother to check to see if it already has the same value integer object.
(It could, but the overhead would likely swamp any savings.)
 
S

skip

Rocco> def f():
Rocco> a = 12100
Rocco> b = 12100
Rocco> c = 121*100
Rocco> print a is b
Rocco> print a is c

That the object with value 12100 is referenced by both a and b is a side
effect of byte code compilation by CPython not an inherent property of
integer objects. Nor is it an optimization performed by CPython on
integers. As literals are collected during compilation they are only
inserted into the local constants tuple once.
... a = "12,100"
... b = "12,100"
... c = "12," + "100"
... print a is b
... print a is c
... True
False (None, '12,100', '12,', '100')
... a = 12100
... b = 12100
... c = 121*100
... print a is b
... print a is c
... True
False (None, 12100, 121, 100)

Skip
 
M

Magnus Lycka

Suresh said:
# I am new to python. [...]
In any application most of the operation is numerical. So, i think, we
should get a good speed advantage with the availability of mutable
numbers. What do you think ?

If you are new to Python, I think you should try to learn how to
use it well, and rest assured that the smart people who have been
working on it for 15 years have done a pretty good job at making
it perform well, with respect to the basic design decisions.

Runtime performance has never been the prime goal for Python. It's
always been more important with clarity, easy of use and programmer
productivity. CPUs get faster and faster, but programmers don't get
smarter and smarter...

Still, it's quite possible to write very capable programs in Python.
For intense number crunching, it's often helpful to use some good
library written in C though, whether it's NumPy or some cryptographic
library.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top