11from __future__ import annotations
2+ import array
23import struct
4+ import sys
35
46try :
57 import numpy as np
@@ -12,19 +14,22 @@ class Vector:
1214 def __init__ (self , value : list [float ] | np .ndarray [tuple [int ], np .dtype [np .floating ]]) -> None :
1315 if isinstance (value , list ):
1416 try :
15- self ._value = [ float ( v ) for v in value ]
16- except ( TypeError , ValueError ) :
17+ self ._value = array . array ( 'f' , value )
18+ except TypeError :
1719 raise ValueError ('expected list[float]' )
1820 elif NUMPY_AVAILABLE and isinstance (value , np .ndarray ):
1921 if value .ndim != 1 :
2022 raise ValueError ('expected ndim to be 1' )
2123
22- self ._value = [float (v ) for v in value ]
24+ if value .dtype != np .float32 :
25+ value = np .asarray (value , dtype = np .float32 )
26+
27+ self ._value = array .array ('f' , value .tobytes ())
2328 else :
2429 raise ValueError ('expected list or ndarray' )
2530
2631 def __repr__ (self ) -> str :
27- return f'Vector({ self ._value } )'
32+ return f'Vector({ self .to_list () } )'
2833
2934 def __eq__ (self , other : object ) -> bool :
3035 if isinstance (other , self .__class__ ):
@@ -35,23 +40,25 @@ def dimensions(self) -> int:
3540 return len (self ._value )
3641
3742 def to_list (self ) -> list [float ]:
38- return self ._value
43+ return self ._value . tolist ()
3944
4045 def to_numpy (self ) -> np .ndarray [tuple [int ], np .dtype [np .float32 ]]:
41- return np .array (self ._value , dtype = np .float32 )
46+ return np .frombuffer (self ._value , dtype = np .float32 )
4247
4348 def to_text (self ) -> str :
4449 return f'[{ "," .join ([str (v ) for v in self ._value ])} ]'
4550
4651 def to_binary (self ) -> bytes :
47- dim = len (self ._value )
48- return struct .pack (f'>HH{ dim } f' , dim , 0 , * self ._value )
52+ if sys .byteorder == 'big' :
53+ value = self ._value
54+ else :
55+ value = array .array ('f' , self ._value )
56+ value .byteswap ()
57+ return struct .pack (f'>HH' , len (value ), 0 ) + value .tobytes ()
4958
5059 @classmethod
5160 def from_text (cls , value : str ) -> Vector :
52- vec = cls .__new__ (cls )
53- vec ._value = [float (v ) for v in value [1 :- 1 ].split (',' )]
54- return vec
61+ return cls ([float (v ) for v in value [1 :- 1 ].split (',' )])
5562
5663 @classmethod
5764 def from_binary (cls , value : bytes ) -> Vector :
@@ -64,7 +71,9 @@ def from_binary(cls, value: bytes) -> Vector:
6471 raise ValueError ('expected unused to be 0' )
6572
6673 vec = cls .__new__ (cls )
67- vec ._value = list (struct .unpack_from (f'>{ dim } f' , value [4 :]))
74+ vec ._value = array .array ('f' , value [4 :])
75+ if sys .byteorder != 'big' :
76+ vec ._value .byteswap ()
6877 return vec
6978
7079 @classmethod
@@ -86,16 +95,6 @@ def _to_db_binary(cls, value: object) -> bytes | None:
8695 if value is None :
8796 return value
8897
89- # fast path for NumPy
90- if NUMPY_AVAILABLE and isinstance (value , np .ndarray ):
91- if value .ndim != 1 :
92- raise ValueError ('expected ndim to be 1' )
93-
94- if value .dtype != '>f4' :
95- value = np .asarray (value , dtype = '>f4' )
96-
97- return struct .pack ('>HH' , len (value ), 0 ) + value .tobytes ()
98-
9998 if not isinstance (value , cls ):
10099 value = cls (value ) # type: ignore
101100
0 commit comments