Commit 1c60884
committed
gh-156955: Speed up csv.writer by not scanning lineterminator per character
join_append_data() tested every character of every field for membership in
dialect->lineterminator with PyUnicode_FindChar(), an out-of-line call made
twice per character (the function runs a count pass and a copy pass). At
54% of cycles it was the single hottest symbol in csv.writer, which made
writing CSV slower than parsing it back.
Cache the terminator's highest code point on the dialect, which is
immutable, and compare inline. Ordinary text exceeds that maximum, so the
membership test is skipped without touching the terminator at all; when it
does run it is a short loop over the terminator's characters rather than a
cross-module call. Membership semantics are unchanged, including
multi-character, empty and non-BMP terminators.
Interleaved A/B, median of 25 per-round ratios, pinned to one CPU:
mixed 2000x4 1.430 ms -> 0.547 ms 2.62x
text 2000x4 1.486 ms -> 0.561 ms 2.64x
wide 500x2 (200ch) 3.159 ms -> 1.094 ms 2.88x
mixed QUOTE_ALL 1.438 ms -> 0.606 ms 2.37x
mixed lineterm='\n' 1.335 ms -> 0.605 ms 2.21x
mixed lineterm='END' 1.535 ms -> 0.822 ms 1.87x
quoted 2000x4 0.486 ms -> 0.323 ms 1.50x
short 5000x4 0.906 ms -> 0.650 ms 1.39x
csv.reader (control) 0.887 ms -> 0.887 ms 1.00x
The maximum is cached on the dialect rather than recomputed per field so
that the change never loses. Degenerate inputs (rows of empty fields, or a
4096-character lineterminator) measure 1.00-1.01x, and a long terminator
with short fields improves from 0.11x to 2.94x against a per-field variant.1 parent 532b9db commit 1c60884
2 files changed
Lines changed: 41 additions & 3 deletions
Lines changed: 3 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
116 | 116 | | |
117 | 117 | | |
118 | 118 | | |
| 119 | + | |
119 | 120 | | |
120 | 121 | | |
121 | 122 | | |
| |||
332 | 333 | | |
333 | 334 | | |
334 | 335 | | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
335 | 352 | | |
336 | 353 | | |
337 | 354 | | |
| |||
533 | 550 | | |
534 | 551 | | |
535 | 552 | | |
| 553 | + | |
536 | 554 | | |
537 | 555 | | |
538 | 556 | | |
| |||
1165 | 1183 | | |
1166 | 1184 | | |
1167 | 1185 | | |
| 1186 | + | |
| 1187 | + | |
| 1188 | + | |
| 1189 | + | |
| 1190 | + | |
| 1191 | + | |
| 1192 | + | |
| 1193 | + | |
| 1194 | + | |
| 1195 | + | |
| 1196 | + | |
| 1197 | + | |
| 1198 | + | |
| 1199 | + | |
| 1200 | + | |
1168 | 1201 | | |
1169 | 1202 | | |
1170 | 1203 | | |
| |||
1176 | 1209 | | |
1177 | 1210 | | |
1178 | 1211 | | |
| 1212 | + | |
| 1213 | + | |
| 1214 | + | |
| 1215 | + | |
1179 | 1216 | | |
1180 | 1217 | | |
1181 | 1218 | | |
| |||
1213 | 1250 | | |
1214 | 1251 | | |
1215 | 1252 | | |
1216 | | - | |
1217 | | - | |
1218 | | - | |
| 1253 | + | |
1219 | 1254 | | |
1220 | 1255 | | |
1221 | 1256 | | |
| |||
0 commit comments