forked from mozman/ezdxf
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconstruct.py
134 lines (107 loc) · 3.63 KB
/
construct.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# Copyright (c) 2020, Manfred Moitzi
# License: MIT License
import sys
import time
from datetime import datetime
from pathlib import Path
from ezdxf.acc import USE_C_EXT
from ezdxf.render.forms import ellipse
if USE_C_EXT is False:
print("C-extension disabled or not available.")
sys.exit(1)
from ezdxf.math._construct import (
has_clockwise_orientation as py_has_clockwise_orientation,
)
from ezdxf.acc.construct import (
has_clockwise_orientation as cy_has_clockwise_orientation,
)
from ezdxf.math._construct import (
intersection_line_line_2d as py_intersection_line_line_2d,
)
from ezdxf.acc.construct import (
intersection_line_line_2d as cy_intersection_line_line_2d,
)
from ezdxf.version import __version__
from ezdxf.acc.vector import Vec2
def open_log(name: str):
parent = Path(__file__).parent
p = parent / "logs" / Path(name + ".csv")
if not p.exists():
with open(p, mode="wt") as fp:
fp.write(
'"timestamp"; "pytime"; "cytime"; '
'"python_version"; "ezdxf_version"\n'
)
log_file = open(p, mode="at")
return log_file
def log(name: str, pytime: float, cytime: float):
log_file = open_log(name)
timestamp = datetime.now().isoformat()
log_file.write(
f'{timestamp}; {pytime}; {cytime}; "{sys.version}"; "{__version__}"\n'
)
log_file.close()
def profile1(func, *args) -> float:
t0 = time.perf_counter()
func(*args)
t1 = time.perf_counter()
return t1 - t0
def profile(text, log_name, pyfunc, cyfunc, *args):
pytime = profile1(pyfunc, *args)
cytime = profile1(cyfunc, *args)
ratio = pytime / cytime
print(f"Python - {text} {pytime:.3f}s")
print(f"Cython - {text} {cytime:.3f}s")
print(f"Ratio {ratio:.1f}x")
log(log_name, pytime, cytime)
def profile_py_has_clockwise_orientation(vertices, count):
for _ in range(count):
py_has_clockwise_orientation(vertices)
def profile_cy_has_clockwise_orientation(vertices, count):
for _ in range(count):
cy_has_clockwise_orientation(vertices)
def profile_py_intersection_line_line_2d(count):
line1 = [Vec2(0, 0), Vec2(2, 0)]
line2 = [Vec2(1, -1), Vec2(1, 1)]
for _ in range(count):
py_intersection_line_line_2d(line1, line2)
def profile_cy_intersection_line_line_2d(count):
line1 = [Vec2(0, 0), Vec2(2, 0)]
line2 = [Vec2(1, -1), Vec2(1, 1)]
for _ in range(count):
cy_intersection_line_line_2d(line1, line2)
def profile_py_no_intersection_line_line_2d(count):
line1 = [Vec2(0, 0), Vec2(2, 0)]
line2 = [Vec2(0, 1), Vec2(2, 1)]
for _ in range(count):
py_intersection_line_line_2d(line1, line2)
def profile_cy_no_intersection_line_line_2d(count):
line1 = [Vec2(0, 0), Vec2(2, 0)]
line2 = [Vec2(0, 1), Vec2(2, 1)]
for _ in range(count):
cy_intersection_line_line_2d(line1, line2)
RUNS = 100_000
ellipse_vertices = list(ellipse(count=100, rx=10, ry=5))
print(f"Profiling 2D construction tools as Python and Cython implementations:")
profile(
f"detect {RUNS}x clockwise orientation of {len(ellipse_vertices)} vertices:",
"c2d_has_clockwise_orientation",
profile_py_has_clockwise_orientation,
profile_cy_has_clockwise_orientation,
ellipse_vertices,
RUNS,
)
profile(
f"detect {RUNS}x real 2D line intersections:",
"c2d_intersection_line_line_2d",
profile_py_intersection_line_line_2d,
profile_cy_intersection_line_line_2d,
RUNS,
)
profile(
f"detect {RUNS}x no 2D line intersections:",
"c2d_no_intersection_line_line_2d",
profile_py_no_intersection_line_line_2d,
profile_cy_no_intersection_line_line_2d,
RUNS,
)