import time
from random import random
from typing import List
def test(arr: List[int] | None = None) -> None:
if not arr:
raise TypeError("Variable arr must exist!")
opp = arr.pop()
def check_time(func, msg):
t0 = time.perf_counter()
func()
print(f"{msg}\ntime - {time.perf_counter() - t0}")
def first_method():
more_arr = [e for e in arr if e > opp]
less_arr = [e for e in arr if e < opp]
return less_arr, more_arr
def second_method():
more_arr, less_arr = [], []
for e in arr:
if e > opp:
more_arr.append(e)
elif e < opp:
less_arr.append(e)
return less_arr, more_arr
check_time(first_method, "first_method")
check_time(second_method, "second_method")
"""
[RESULT]
first_method
time - 0.1035286999976961
second_method
time - 0.12783881399809616
"""
def main() -> None:
test([int(random() * 1000) for _ in range(1_000_000)])
if __name__ == '__main__':
main()
RESULT:
first_method: time - 0.10790603799978271
second_method: time - 0.1264369229975273
-------------------------------------------------------------
I wont to know why first_method() faster then second_method()?
How work "if" condition in list_comprehension from the point of view of optimization?
Add this third method to see that the retrieving of the append
methods needs a lot of time:
def third_method():
more_arr, less_arr = [], []
m = more_arr.append
l = less_arr.append
for e in arr:
if e > opp:
m(e)
elif e < opp:
l(e)
return less_arr, more_arr
This method is usually even slightly faster than the first one.