[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] vector type: mutable or immutable



Gregor Lingl wrote:


Lorenz Quack schrieb:
Hi again,

I just did a quick performance test.
The first run uses an in-place operation (as could be used with mutable types) the second run on the other hand uses the equivalent expression without the in-place operator (as would be necessary if we go with immutable types).
Hi Lorenz,

I'd propose not to confuse two things:
(1) use of syntax x = x + x versus x += x
(2) use of immutable versus mutable datatypes

In python you can write

 >>> a = 2
 >>> a = a + a
 >>> a
4

as well as

 >>> a += a
 >>> a
8

although the int type is immutable.

true, but as a performance test I think my approach is still valid because if you do
>>> a = 2
>>> a += a
I believe the interpreter internally takes the two operands (in this case a and a) adds them and then rebinds the result to a (the id changes) so effectively doing
>>> a = a + a
exactly because a is immutable
if a were mutable the two expressions would be indeed different the += version would not create a new instance and rebind the name a to it but modify the object a is referring to, while a = a + a would again create a new object and rebind it.
So therefore I believe that this test does make sense.
Tell me if I'm wrong somewhere.


here are the calls with the results:

>>> timeit.repeat("x += x", "from vector import Vector2d; x = Vector2d(2, 3)", repeat=5, number=10000000)
[1.4092800617218018,
 1.4093708992004395,
 1.4093561172485352,
 1.413952112197876,
 1.4092509746551514]
Can you explain a bit how you implemented this. Seems miraculous to me as
even for plain integers I get:

 >>> timeit.repeat("x += x", "x = 2", number=1000)
[0.00030635119219368789, 0.00030155776880746998, 0.000303348264651504]
 >>> timeit.repeat("x += x", "x = 2", number=10000)
[0.023589079352177578, 0.023484539926357684, 0.023433343760189018]
 >>> timeit.repeat("x += x", "x = 2", number=100000)
[2.1454171779987519, 2.1408996934512743, 2.1383358762293483]

highly nonlinear, which seems to have its cause in

 >>> x

[snip very large number]


which has more than 30000 digits. Which result did you get after 10000000 executions of the statement x = x + x?

And which implementation of the long integer type did you use that is that much faster than Python's ?

Regards,
Gregor


indeed those are valid objections. well first of all I used a self-written C extension with double as the underlying type. but the result after 1023 iterations turns into (inf, inf). this could of course invalidate the results so I modified the test:

>>> timeit.repeat("x = Vector2d(2,3); x += x", "from vector import Vector2d", repeat=5, number=10000000)
[5.1832518577575684,
 5.1106431484222412,
 5.1510121822357178,
 5.0923140048980713,
 5.0608019828796387]

>>> timeit.repeat("x = Vector2d(2,3); x = x + x", "from vector import Vector2d", repeat=5, number=10000000)
[6.5348029136657715,
 6.3499071598052979,
 6.4433431625366211,
 6.412431001663208,
 6.4398849010467529]

>>> timeit.repeat("x = Vector2d(2,3)", "from vector import Vector2d", repeat=5, number=10000000)
[3.7264928817749023,
 3.6346859931945801,
 3.6241021156311035,
 3.7733709812164307,
 3.6264529228210449]

so the numbers change but the overall result stays the same.


//Lorenz



>>> timeit.repeat("x = x + x", "from vector import Vector2d; x = Vector2d(2, 3)", repeat=5, number=10000000)
[2.3679590225219727,
 2.3530960083007812,
 2.3615989685058594,
 2.3519301414489746,
 2.3658668994903564]

that is quite an overhead IMHO.
Of course it is quite possible you could tweak this a bit but I imagine the result would stay more or less the same.

Note that the vector type in this example was implemented as C extension.

This make me once more lean towards mutable.



Lorenz Quack wrote:
Hi,

I'm against implementing both. I think it makes what should be a rather simple class overcomplicated. Imagine the zoo of class we would have:
Vector2d, Vector2dConst, IntVector2d IntVectro2dConst, Vector3d, ...

I think we should make up our minds and then sick with one.

And I have to add that even though I started off favoring mutable vectors I then remembered also running into the subtle bugs Brian mentioned. So now I'm leaning in the immutable direction.



Brian Fisher wrote:
I guess making both would be the most pythonic - python gives you both lists and tuples...

On Fri, May 1, 2009 at 11:04 AM, Jake b <ninmonkeys@xxxxxxxxx <mailto:ninmonkeys@xxxxxxxxx>> wrote:

Could you make both? Default to mutable, and use VectorConst ( insert
    better name ) where needed.

           .offset = Vector3Const(1,2,3)
           .vel = Vector3( offset )

    (throw exception when you try to modify a const vector?)
    --
    Jake