diff --git a/android_env/components/pixel_fns.py b/android_env/components/pixel_fns.py index 77f129b..d00a334 100644 --- a/android_env/components/pixel_fns.py +++ b/android_env/components/pixel_fns.py @@ -26,9 +26,11 @@ def touch_position_to_pixel_position( width_height: Sequence[int], ) -> tuple[int, int]: """Maps touch position in [0,1] to the corresponding pixel on the screen.""" - touch_pixels = (touch_position * width_height).astype(np.int32) - cap_idx = lambda v, idx_len: min(v, idx_len - 1) - return tuple(map(cap_idx, touch_pixels, width_height)) + # Unpack and use pure Python math to avoid NumPy overhead for small 2D array. + # Also avoids map/lambda overhead. + x, y = touch_position + w, h = width_height + return (min(int(x * w), w - 1), min(int(y * h), h - 1)) def transpose_pixels(frame: np.ndarray) -> np.ndarray: diff --git a/android_env/components/pixel_fns_test.py b/android_env/components/pixel_fns_test.py index fcbdd76..59bca44 100644 --- a/android_env/components/pixel_fns_test.py +++ b/android_env/components/pixel_fns_test.py @@ -137,8 +137,8 @@ def test_touch_position_to_pixel_position(self): number = 100000 res = t.timeit(number=number) print( - f'\ntouch_position_to_pixel_position: {res / number * 1e6:.3f} us per' - ' loop' + f'BenchmarkTouchPositionToPixelPosition {number}' + f' {res / number * 1e9:.0f} ns/op' ) def test_transpose_pixels(self): @@ -151,17 +151,15 @@ def test_transpose_pixels(self): t = timeit.Timer(stmt, setup=setup) number = 1000 res = t.timeit(number=number) - print( - f'\ntranspose_pixels {size} (view): {res / number * 1e3:.3f} ms per' - ' loop' - ) + name_view = f'TransposePixels_{size[0]}x{size[1]}_view' + print(f'Benchmark{name_view} {number} {res / number * 1e9:.0f} ns/op') stmt_copy = 'pixel_fns.transpose_pixels(img).copy()' t_copy = timeit.Timer(stmt_copy, setup=setup) res_copy = t_copy.timeit(number=number) + name_copy = f'TransposePixels_{size[0]}x{size[1]}_copy' print( - f'transpose_pixels {size} (copy): {res_copy / number * 1e3:.3f} ms' - ' per loop' + f'Benchmark{name_copy} {number} {res_copy / number * 1e9:.0f} ns/op' ) def test_orient_pixels(self): @@ -176,17 +174,15 @@ def test_orient_pixels(self): t = timeit.Timer(stmt, setup=setup) number = 1000 res = t.timeit(number=number) - print( - f'\norient_pixels {size}, orientation={orientation} (view):' - f' {res / number * 1e3:.3f} ms per loop' - ) + name_view = f'OrientPixels_{size[0]}x{size[1]}_rot{orientation}_view' + print(f'Benchmark{name_view} {number} {res / number * 1e9:.0f} ns/op') stmt_copy = 'pixel_fns.orient_pixels(img, orientation).copy()' t_copy = timeit.Timer(stmt_copy, setup=setup) res_copy = t_copy.timeit(number=number) + name_copy = f'OrientPixels_{size[0]}x{size[1]}_rot{orientation}_copy' print( - f'orient_pixels {size}, orientation={orientation} (copy):' - f' {res_copy / number * 1e3:.3f} ms per loop' + f'Benchmark{name_copy} {number} {res_copy / number * 1e9:.0f} ns/op' ) def test_convert_int_to_float(self): @@ -203,10 +199,8 @@ def test_convert_int_to_float(self): t = timeit.Timer(stmt, setup=setup) number = 100 res = t.timeit(number=number) - print( - f'\nconvert_int_to_float {size} (BoundedArray):' - f' {res / number * 1e3:.3f} ms per loop' - ) + name = f'ConvertIntToFloat_{size[0]}x{size[1]}_BoundedArray' + print(f'Benchmark{name} {number} {res / number * 1e9:.0f} ns/op') if __name__ == '__main__':