Skip to content

Commit 2fed4a7

Browse files
committed
Stop developing for @Native
1 parent c4ce97d commit 2fed4a7

File tree

7 files changed

+97
-16
lines changed

7 files changed

+97
-16
lines changed

.idea/PyFastUtil.iml

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyfastutil/native/_internal/BytecodeTranslator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,5 +311,5 @@ def visit(self, op: str, arg: Optional[int], argVal: Any) -> None:
311311

312312

313313
# noinspection PyUnusedLocal
314-
def toC(func: FunctionType, arguments: Iterable[Parameter], bytecode: Bytecode, c_int: bool) -> list[str]:
314+
def toC(func: FunctionType, arguments: Iterable[Parameter], bytecode: Bytecode) -> list[str]:
315315
return _BytecodeTranslator(func, arguments, bytecode).run()

pyfastutil/native/_internal/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
NATIVE_CACHE: dict[str, BuiltinFunctionType | FunctionType] = {}
1616

1717

18-
def native(func: FunctionType, c_int: bool = False) -> BuiltinFunctionType | FunctionType:
18+
def native(func: FunctionType) -> BuiltinFunctionType | FunctionType:
1919
# initialization
2020
params = inspect.signature(func).parameters.values()
2121
bytecode = Bytecode(func)
@@ -36,7 +36,7 @@ def native(func: FunctionType, c_int: bool = False) -> BuiltinFunctionType | Fun
3636

3737
# compile
3838
try:
39-
Compiler.compileCode(cacheFolder, func.__name__, moduleName, BytecodeTranslator.toC(func, params, bytecode, c_int))
39+
Compiler.compileCode(cacheFolder, func.__name__, moduleName, BytecodeTranslator.toC(func, params, bytecode))
4040
except NotImplementedError:
4141
NATIVE_CACHE[hashed] = func
4242
return func

pyfastutil/native/annotations.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,10 @@
11
from types import FunctionType
2-
from typing import TypeVar, overload, Callable
2+
from typing import TypeVar
33

44
from ._internal import native as _native
55

66
__T = TypeVar("__T", bound=FunctionType)
77

88

9-
@overload
10-
def native(func: __T) -> __T: ...
11-
12-
13-
@overload
14-
def native(c_int: bool = False) -> Callable[[__T], __T]: ...
15-
16-
17-
def native(arg: __T | bool = None):
18-
return _native(arg) if type(arg) is FunctionType else _native(arg, c_int=True)
9+
def native(func: __T) -> __T:
10+
return _native(func)

tests/benchmark/benchmark_Native.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
from pyfastutil.native import native
44

5-
SIZE = 100000
6-
REPEAT = 100
5+
SIZE = 1000000
6+
REPEAT = 10
77

88

99
def python(n):
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import sys
2+
sys.path.append("D:\\PyFastUtil")
3+
from typing import Optional
4+
from keystone import Ks, KS_ARCH_X86, KS_MODE_64
5+
from pyfastutil.unsafe import Ptr, Unsafe, ASM
6+
import timeit
7+
from pyfastutil.native import native
8+
9+
SIZE = 2000
10+
REPEAT = 20
11+
12+
ks = Ks(KS_ARCH_X86, KS_MODE_64)
13+
asmFunc: Optional[Ptr] = None
14+
15+
16+
def python(n):
17+
x = 0
18+
for i in range(n):
19+
x += i * i
20+
return x
21+
22+
23+
@native
24+
def native(n):
25+
x = 0
26+
for i in range(n):
27+
x += i * i
28+
return x
29+
30+
31+
def setupAsm():
32+
global asmFunc
33+
34+
asmCode = f"""
35+
mov rax, 0 # x = 0
36+
mov r10, 0 # i = 0
37+
for:
38+
cmp r10, {SIZE} # if i >= {SIZE}
39+
jnl end
40+
mov r11, r10 # i * i
41+
imul r11, r11
42+
add rax, r11 # x += i * i
43+
inc r10 # i += 1
44+
jmp for
45+
46+
end:
47+
ret
48+
"""
49+
50+
with ASM() as asm:
51+
asmFunc = asm.makeFunction(ks.asm(asmCode, as_bytes=True)[0])
52+
53+
54+
def realNative():
55+
with Unsafe() as unsafe:
56+
return unsafe.callLongLong(asmFunc)
57+
58+
59+
def main():
60+
global SIZE
61+
print(f"---Python & Native & Real-Native for Benchmark---")
62+
print(f"Batch size: {SIZE}")
63+
print(f"Repeat: {REPEAT}\n")
64+
65+
setupAsm()
66+
assert python(SIZE) == native(SIZE) == realNative()
67+
assert native.__doc__ == "<native method>"
68+
69+
time_python = sum(timeit.repeat(lambda: python(SIZE), repeat=REPEAT, number=1)) / REPEAT
70+
time_native = sum(timeit.repeat(lambda: native(SIZE), repeat=REPEAT, number=1)) / REPEAT
71+
time_realNative = sum(timeit.repeat(realNative, repeat=REPEAT, number=1)) / REPEAT
72+
speed = time_python / time_native * 100
73+
speed2 = time_python / time_realNative * 100
74+
75+
print(f"Python time: {time_python * 1000:.2f} ms")
76+
print(f"Native time: {time_native * 1000:.2f} ms")
77+
print(f"Real-Native time: {time_realNative * 1000:.2f} ms\n")
78+
print(f"Native speed of Python: {speed:.2f} %")
79+
print(f"Real-Native speed of Python: {speed2:.2f} %\n")
80+
81+
with ASM() as asm:
82+
asm.freeFunction(asmFunc)
83+
84+
85+
if __name__ == '__main__':
86+
main()

tests/test_native.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from pyfastutil.native import native
44

55

6+
@unittest.skipUnless(False, "@native is ")
67
class TestNative(unittest.TestCase):
78
def test_add(self):
89
def add(x, y):

0 commit comments

Comments
 (0)