|
1 |
| -import collections |
| 1 | +from collections import namedtuple |
2 | 2 | import datetime
|
3 | 3 | import timeit
|
4 | 4 | import argparse
|
| 5 | +import typing as tp |
| 6 | +from enum import Enum |
5 | 7 |
|
6 | 8 | import numpy as np
|
7 | 9 |
|
|
17 | 19 | from performance.reference.util import dtype_from_element as dtype_from_element_ref
|
18 | 20 | from performance.reference.util import array_deepcopy as array_deepcopy_ref
|
19 | 21 | from performance.reference.util import isna_element as isna_element_ref
|
| 22 | +from performance.reference.util import get_new_indexers_and_screen_ak |
| 23 | +from performance.reference.util import get_new_indexers_and_screen_ref |
20 | 24 |
|
21 | 25 | from performance.reference.array_go import ArrayGO as ArrayGOREF
|
22 | 26 |
|
@@ -258,7 +262,7 @@ class DtypeFromElementPerf(Perf):
|
258 | 262 | NUMBER = 1000
|
259 | 263 |
|
260 | 264 | def __init__(self):
|
261 |
| - NT = collections.namedtuple('NT', tuple('abc')) |
| 265 | + NT = namedtuple('NT', tuple('abc')) |
262 | 266 |
|
263 | 267 | self.values = [
|
264 | 268 | np.longlong(-1), np.int_(-1), np.intc(-1), np.short(-1), np.byte(-1),
|
@@ -359,6 +363,103 @@ class IsNaElementPerfREF(IsNaElementPerf):
|
359 | 363 | entry = staticmethod(isna_element_ref)
|
360 | 364 |
|
361 | 365 |
|
| 366 | +#------------------------------------------------------------------------------- |
| 367 | +class GetNewIndexersAndScreenPerf(Perf): |
| 368 | + FUNCTIONS = ( |
| 369 | + "ordered", |
| 370 | + "unordered", |
| 371 | + "tiled", |
| 372 | + "repeat", |
| 373 | + "quick_exit", |
| 374 | + "late_exit", |
| 375 | + "small", |
| 376 | + "large", |
| 377 | + ) |
| 378 | + NUMBER = 5 |
| 379 | + |
| 380 | + TILED = "tiled" |
| 381 | + REPEATED = "repeated" |
| 382 | + ORDERED = "ordered" |
| 383 | + UNORDERED = "unordered" |
| 384 | + |
| 385 | + class Key(tp.NamedTuple): |
| 386 | + type1: str |
| 387 | + type2: str |
| 388 | + increment: int |
| 389 | + scale: int |
| 390 | + |
| 391 | + def __init__(self): |
| 392 | + NUMBERS = np.arange(500_000, dtype=np.int64) |
| 393 | + POSITIONS = np.arange(500_000, dtype=np.int64) |
| 394 | + |
| 395 | + np.random.seed(0) |
| 396 | + |
| 397 | + self.cases: tp.Dict[self.Key, tp.Tuple[np.ndarray, np.ndarray]] = {} |
| 398 | + |
| 399 | + for scale in (5, 50, 500, 5_000, 50_000): |
| 400 | + tiled_ordered = np.tile(NUMBERS[:scale], len(NUMBERS) // scale) |
| 401 | + repeated_ordered = np.repeat(NUMBERS[:scale], len(NUMBERS) // scale) |
| 402 | + tiled_unordered = tiled_ordered.copy() |
| 403 | + repeated_unordered = repeated_ordered.copy() |
| 404 | + np.random.shuffle(tiled_unordered) |
| 405 | + np.random.shuffle(repeated_unordered) |
| 406 | + |
| 407 | + increment = scale |
| 408 | + while increment <= len(NUMBERS): |
| 409 | + positions = POSITIONS[:increment] |
| 410 | + key_kwargs = dict(increment=increment, scale=scale) |
| 411 | + self.cases[ |
| 412 | + self.Key(type1=self.TILED, type2=self.ORDERED, **key_kwargs) |
| 413 | + ] = (tiled_ordered, positions) |
| 414 | + self.cases[ |
| 415 | + self.Key(type1=self.REPEATED, type2=self.ORDERED, **key_kwargs) |
| 416 | + ] = (repeated_ordered, positions) |
| 417 | + self.cases[ |
| 418 | + self.Key(type1=self.TILED, type2=self.UNORDERED, **key_kwargs) |
| 419 | + ] = (tiled_unordered, positions) |
| 420 | + self.cases[ |
| 421 | + self.Key(type1=self.REPEATED, type2=self.UNORDERED, **key_kwargs) |
| 422 | + ] = (repeated_unordered, positions) |
| 423 | + increment *= 10 |
| 424 | + |
| 425 | + def evaluate_cases_by_condition(self, condition): |
| 426 | + for key, (indexers, positions) in self.cases.items(): |
| 427 | + if condition(key): |
| 428 | + self.entry(indexers=indexers, positions=positions) |
| 429 | + |
| 430 | + def ordered(self): |
| 431 | + self.evaluate_cases_by_condition(lambda key: key.type2 == self.ORDERED) |
| 432 | + |
| 433 | + def unordered(self): |
| 434 | + self.evaluate_cases_by_condition(lambda key: key.type2 == self.UNORDERED) |
| 435 | + |
| 436 | + def tiled(self): |
| 437 | + self.evaluate_cases_by_condition(lambda key: key.type1 == self.TILED) |
| 438 | + |
| 439 | + def repeat(self): |
| 440 | + self.evaluate_cases_by_condition(lambda key: key.type1 == self.REPEATED) |
| 441 | + |
| 442 | + def quick_exit(self): |
| 443 | + self.evaluate_cases_by_condition(lambda key: key.increment == key.scale) |
| 444 | + |
| 445 | + def late_exit(self): |
| 446 | + self.evaluate_cases_by_condition(lambda key: key.increment > key.scale) |
| 447 | + |
| 448 | + def small(self): |
| 449 | + self.evaluate_cases_by_condition(lambda key: key.scale <= 500) |
| 450 | + |
| 451 | + def large(self): |
| 452 | + self.evaluate_cases_by_condition(lambda key: key.scale > 500) |
| 453 | + |
| 454 | + |
| 455 | +class GetNewIndexersAndScreenPerfAK(GetNewIndexersAndScreenPerf): |
| 456 | + entry = staticmethod(get_new_indexers_and_screen_ak) |
| 457 | + |
| 458 | + |
| 459 | +class GetNewIndexersAndScreenPerfREF(GetNewIndexersAndScreenPerf): |
| 460 | + entry = staticmethod(get_new_indexers_and_screen_ref) |
| 461 | + |
| 462 | + |
362 | 463 | #-------------------------------------------------------------------------------
|
363 | 464 |
|
364 | 465 | def get_arg_parser():
|
@@ -399,7 +500,7 @@ def main():
|
399 | 500 | number=cls_runner.NUMBER)
|
400 | 501 | records.append((cls_perf.__name__, func_attr, results['ak'], results['ref'], results['ref'] / results['ak']))
|
401 | 502 |
|
402 |
| - width = 24 |
| 503 | + width = 32 |
403 | 504 | for record in records:
|
404 | 505 | print(''.join(
|
405 | 506 | (r.ljust(width) if isinstance(r, str) else str(round(r, 8)).ljust(width)) for r in record
|
|
0 commit comments