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

Re: [pygame] Re: removing 'experimental' notice from pygame.math



Oh yes. Thanks.

TLDR; those are fixed. Should pygame.Vector2 and Vector2 go in pygame.locals by default?



a) I fixed it so it returns a Vector2, or Vector3 as is appropriate.
Something like v.xyxy (length==4) returns a tuple.
type(v.xy) == float
type(v.xy) == Vector2
type(v.xyz) == Vector3
type(v.xyzx) == tuple

b) v.x = 3 works again.
c) updated the docs, removed experimental notice.
d) swizzling is now faster than fetching single attributes. (v.xyz is faster than (v.x, v.y, v.z)).

    In [1]: import pygame.math
    In [2]: v = pygame.math.Vector3(1,2,3)
    In [3]: %timeit v.xyz
    The slowest run took 230.33 times longer than the fastest. This could mean that an intermediate result is being cached.
    10000000 loops, best of 3: 77.8 ns per loop
    In [4]: %timeit pygame.math.Vector3(v.x, v.y, v.z)
    The slowest run took 25.69 times longer than the fastest. This could mean that an intermediate result is being cached.
    1000000 loops, best of 3: 465 ns per loop

    In [5]: %timeit v.xy
    The slowest run took 25.73 times longer than the fastest. This could mean that an intermediate result is being cached.
    10000000 loops, best of 3: 73.5 ns per loop
    In [6]: %timeit (v.x, v.y)
    The slowest run took 18.30 times longer than the fastest. This could mean that an intermediate result is being cached.
    10000000 loops, best of 3: 135 ns per loop
    In [7]: %timeit pygame.math.Vector2(v.x, v.y)
    The slowest run took 31.03 times longer than the fastest. This could mean that an intermediate result is being cached.
    1000000 loops, best of 3: 353 ns per loop
    In [8]: Vector2 = pygame.math.Vector2
    In [9]: %timeit Vector2(v.x, v.y)
    The slowest run took 13.55 times longer than the fastest. This could mean that an intermediate result is being cached.
    1000000 loops, best of 3: 310 ns per loop

This was because before it was handling swizzle attribute access by waiting for an error.

Now, (x,y,z) attribute access is just as fast, and swizzles are a lot faster.
However other methods are about 10ns slower (on this machine).

    In [10]: pygame.math.disable_swizzling()
    In [11]: %timeit v.is_normalized()
    The slowest run took 28.18 times longer than the fastest. This could mean that an intermediate result is being cached.
    10000000 loops, best of 3: 83.3 ns per loop
    In [12]: pygame.math.enable_swizzling()
    In [13]: %timeit v.is_normalized()
    The slowest run took 28.89 times longer than the fastest. This could mean that an intermediate result is being cached.
    10000000 loops, best of 3: 94.1 ns per loop


Another downside of Vectors at the moment is that they allocate more slowly than tuples.
Because python tuples and lists are optimized over normal objects, and use a memory pool.
However, it's close to list if you use the list() constructor, and 2x faster than a python object.

    In [1]: import pygame.math
    In [2]: v=pygame.math.Vector2(1,2)
    In [3]: Vector2 = pygame.math.Vector2
    In [4]: %timeit Vector2(1.0,2.0)
    The slowest run took 11.90 times longer than the fastest. This could mean that an intermediate result is being cached.
    10000000 loops, best of 3: 197 ns per loop
    In [5]: %timeit (1.0,2.0)
    100000000 loops, best of 3: 14.5 ns per loop
    In [6]: %timeit list((1,2))
    The slowest run took 5.76 times longer than the fastest. This could mean that an intermediate result is being cached.
    1000000 loops, best of 3: 205 ns per loop
    In [7]: class V(object):
       ...:     def __init__(self, x, y):
       ...:         self.x = x
       ...:         self.y = y
       ...:        
    In [8]: %timeit V(1,2)
    The slowest run took 5.96 times longer than the fastest. This could mean that an intermediate result is being cached.
    1000000 loops, best of 3: 422 ns per loop


https://github.com/pygame/pygame/pull/403





What about?
1) Putting them in pygame.Vector2, pygame.Vector3 and in pygame.locals? pygame.math imported by default.

Some other topics/issues... (perhaps all for later?)

- types in python are spelt with a lower case these days (post python 1.5.2 *ahem*).
- We should probably call them vec2, vec3 as per GLSL (and as per python naming of types).
- We are missing other swizzle attribute names from GLSL, like rgba.
- There is some support in the code for Vector4... but a number of the methods would need to be written first.
- Now that vectors have this nice slicing/swizzling support... what about colors and rects?
- Should all types be consistently lower case? color, rect? 'rect' is used a lot in code... to mean an instance Maybe not.
- there's some commented out code for buffer handling. Useful when you want a vector to act on a bigger list of data.
- allocation of new vectors could be improved perhaps to approach tuple speed?




On Sun, Feb 25, 2018 at 12:05 PM, Daniel Pope <mauve@xxxxxxxxxxxxxx> wrote:
Indeed, getting the attribute returns a float so the attribute should be settable as a float for consistency.

If users are familiar with GLSL[1], they might be surprised that the type of vectors returned by swizzle attribute access is not a vector:

>>> from pygame.math import Vector3, enable_swizzling
>>> enable_swizzling()
>>> Vector3()
<Vector3(0, 0, 0)>
>>> v = Vector3(1, 2, 3)                                                                                     
>>> v.xy
(1.0, 2.0)
>>> type(v.xy)
<class 'tuple'>



On Sun, 25 Feb 2018 at 09:38 René Dudfield <renesd@xxxxxxxxx> wrote:
Hi,

that's a good point.

TLDR; I think it should be on by default too. There's still a couple of issues with doing that.


It should have _no_ cost in almost all cases for attribute access. Because it first tries normal attribute access.
See: https://github.com/pygame/pygame/blob/master/src/math.c#L1517

I guess the reason is it's off by default is because it was implemented later on, and to leave it on in a buggy state caused issues.

Not a big concern, but turning it on by default will perhaps have annoying compatibility issues for people using an old pygame.
If they forget to turn it on.

There's two test failures once I changed to be enabled by default:

>>> import pygame.math
>>> v = pygame.math.Vector2(1,2)
>>> v.x = 3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: a sequence is expected
>>> pygame.math.disable_swizzling()
>>> v.x = 3
>>> v
<Vector2(3, 2)>

These are to do with assignment to a variable.

On Sat, Feb 24, 2018 at 7:23 PM, Daniel Pope <mauve@xxxxxxxxxxxxxx> wrote:
Does the Swizzling have a cost if you're not using it? If not I'd be tempted to say it should always be on.


On Sat, 24 Feb 2018, 18:00 René Dudfield, <renesd@xxxxxxxxx> wrote:
Hey hey,

I noticed the pygame.math vectors couldn't be pickled/unpickled.

So that has been added here:
https://github.com/pygame/pygame/pull/403

Could someone please review?


cheers,



On Sat, Feb 24, 2018 at 10:30 AM, René Dudfield <renesd@xxxxxxxxx> wrote:
Hello,

I'm going to remove the experimental notice from pygame.math in the docs.
https://www.pygame.org/docs/ref/math.html

It seems fine to me, and I guess no one has plans to change it?


best regards,