Skip to content

Commit a89fef6

Browse files
authored
Merge pull request #210 from static-frame/copilot/buffered-byte-writing
Add C-level buffered array writer with direct file descriptor writes
2 parents ea02688 + bf636b5 commit a89fef6

37 files changed

Lines changed: 2985 additions & 2042 deletions

doc/articles/array_to_tuple_array.py

Lines changed: 56 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,24 @@
1212

1313
sys.path.append(os.getcwd())
1414

15+
1516
class ArrayProcessor:
1617
NAME = ''
1718
SORT = -1
1819

1920
def __init__(self, array: np.ndarray):
2021
self.array = array
2122

22-
#-------------------------------------------------------------------------------
23+
24+
# -------------------------------------------------------------------------------
2325
class AKArray2D1D(ArrayProcessor):
2426
NAME = 'ak.array_to_tuple_array()'
2527
SORT = 0
2628

2729
def __call__(self):
2830
_ = array_to_tuple_array(self.array)
2931

32+
3033
class PyArray2D1D(ArrayProcessor):
3134
NAME = 'Python construction'
3235
SORT = 1
@@ -41,9 +44,11 @@ def __call__(self):
4144
post[i] = tuple(row)
4245
post.flags.writeable = False
4346

44-
#-------------------------------------------------------------------------------
47+
48+
# -------------------------------------------------------------------------------
4549
NUMBER = 200
4650

51+
4752
def seconds_to_display(seconds: float) -> str:
4853
seconds /= NUMBER
4954
if seconds < 1e-4:
@@ -67,9 +72,12 @@ def plot_performance(frame):
6772
# category is the size of the array
6873
for cat_count, (cat_label, cat) in enumerate(frame.groupby('size')):
6974
# each fixture is a collection of tests for one display
70-
fixtures = {fixture_label: fixture for fixture_label, fixture in cat.groupby('fixture')}
75+
fixtures = {
76+
fixture_label: fixture for fixture_label, fixture in cat.groupby('fixture')
77+
}
7178
for fixture_count, (fixture_label, fixture) in enumerate(
72-
(k, fixtures[k]) for k in FixtureFactory.DENSITY_TO_DISPLAY):
79+
(k, fixtures[k]) for k in FixtureFactory.DENSITY_TO_DISPLAY
80+
):
7381
ax = axes[cat_count][fixture_count]
7482

7583
# set order
@@ -87,37 +95,46 @@ def plot_performance(frame):
8795
title = f'{cat_label:.0e}\n{FixtureFactory.DENSITY_TO_DISPLAY[fixture_label]}'
8896

8997
ax.set_title(title, fontsize=6)
90-
ax.set_box_aspect(0.75) # makes taller than wide
98+
ax.set_box_aspect(0.75) # makes taller than wide
9199
time_max = fixture['time'].max()
92100
ax.set_yticks([0, time_max * 0.5, time_max])
93-
ax.set_yticklabels(['',
94-
seconds_to_display(time_max * .5),
101+
ax.set_yticklabels(
102+
[
103+
'',
104+
seconds_to_display(time_max * 0.5),
95105
seconds_to_display(time_max),
96-
], fontsize=4)
106+
],
107+
fontsize=4,
108+
)
97109
# ax.set_xticks(x, names_display, rotation='vertical')
98110
ax.tick_params(
99-
axis='x',
100-
which='both',
101-
bottom=False,
102-
top=False,
103-
labelbottom=False,
104-
)
105-
106-
fig.set_size_inches(8, 4) # width, height
111+
axis='x',
112+
which='both',
113+
bottom=False,
114+
top=False,
115+
labelbottom=False,
116+
)
117+
118+
fig.set_size_inches(8, 4) # width, height
107119
fig.legend(post, names_display, loc='center right', fontsize=6)
108120
# horizontal, vertical
109-
fig.text(.05, .96, f'array_to_tuple_array() Performance: {NUMBER} Iterations', fontsize=10)
110-
fig.text(.05, .90, get_versions(), fontsize=6)
121+
fig.text(
122+
0.05,
123+
0.96,
124+
f'array_to_tuple_array() Performance: {NUMBER} Iterations',
125+
fontsize=10,
126+
)
127+
fig.text(0.05, 0.90, get_versions(), fontsize=6)
111128

112129
fp = '/tmp/array_to_tuple_array.png'
113130
plt.subplots_adjust(
114-
left=0.05,
115-
bottom=0.05,
116-
right=0.8,
117-
top=0.85,
118-
wspace=1.0, # width
119-
hspace=0.5,
120-
)
131+
left=0.05,
132+
bottom=0.05,
133+
right=0.8,
134+
top=0.85,
135+
wspace=1.0, # width
136+
hspace=0.5,
137+
)
121138
# plt.rcParams.update({'font.size': 22})
122139
plt.savefig(fp, dpi=300)
123140

@@ -127,7 +144,8 @@ def plot_performance(frame):
127144
os.system(f'open {fp}')
128145

129146

130-
#-------------------------------------------------------------------------------
147+
# -------------------------------------------------------------------------------
148+
131149

132150
class FixtureFactory:
133151
NAME = ''
@@ -136,7 +154,7 @@ class FixtureFactory:
136154
def get_array(size: int, width_ratio: int) -> np.ndarray:
137155
if width_ratio > 1:
138156
return np.arange(size).reshape(size // width_ratio, width_ratio)
139-
return np.arange(size) # return 1D array
157+
return np.arange(size) # return 1D array
140158

141159
@classmethod
142160
def get_label_array(cls, size: int) -> tp.Tuple[str, np.ndarray]:
@@ -174,6 +192,7 @@ def get_array(size: int) -> np.ndarray:
174192
a = FixtureFactory.get_array(size, 2)
175193
return a
176194

195+
177196
class FFC5(FixtureFactory):
178197
NAME = 'column-5'
179198

@@ -182,6 +201,7 @@ def get_array(size: int) -> np.ndarray:
182201
a = FixtureFactory.get_array(size, 5)
183202
return a
184203

204+
185205
class FFC10(FixtureFactory):
186206
NAME = 'column-10'
187207

@@ -190,6 +210,7 @@ def get_array(size: int) -> np.ndarray:
190210
a = FixtureFactory.get_array(size, 10)
191211
return a
192212

213+
193214
class FFC20(FixtureFactory):
194215
NAME = 'column-20'
195216

@@ -198,15 +219,17 @@ def get_array(size: int) -> np.ndarray:
198219
a = FixtureFactory.get_array(size, 20)
199220
return a
200221

222+
201223
def get_versions() -> str:
202224
import platform
225+
203226
return f'OS: {platform.system()} / ArrayKit: {ak.__version__} / NumPy: {np.__version__}\n'
204227

205228

206229
CLS_PROCESSOR = (
207230
AKArray2D1D,
208231
PyArray2D1D,
209-
)
232+
)
210233

211234
CLS_FF = (
212235
FFC1,
@@ -228,26 +251,20 @@ def run_test():
228251
record = [cls, NUMBER, fixture_label, size]
229252
print(record)
230253
try:
231-
result = timeit.timeit(
232-
f'runner()',
233-
globals=locals(),
234-
number=NUMBER)
254+
result = timeit.timeit(f'runner()', globals=locals(), number=NUMBER)
235255
except OSError:
236256
result = np.nan
237257
finally:
238258
pass
239259
record.append(result)
240260
records.append(record)
241261

242-
f = pd.DataFrame.from_records(records,
243-
columns=('cls_processor', 'number', 'fixture', 'size', 'time')
244-
)
262+
f = pd.DataFrame.from_records(
263+
records, columns=('cls_processor', 'number', 'fixture', 'size', 'time')
264+
)
245265
print(f)
246266
plot_performance(f)
247267

248-
if __name__ == '__main__':
249268

269+
if __name__ == '__main__':
250270
run_test()
251-
252-
253-

0 commit comments

Comments
 (0)