Last active
August 8, 2024 12:09
-
-
Save p1-dta/e9c4210a5545d8447ecd35dad8a43355 to your computer and use it in GitHub Desktop.
Count how many people are alive per year, based on their birthyear and deathyear, aims for performances.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import collections | |
import random | |
import timeit | |
pop = [ | |
(b := random.randint(1900, 2000), random.randint(b + 1, b + 100)) | |
for _ in range(10000) | |
] | |
# 0.162 s (with 10000 people [1,100] years old) | |
def count_living_per_year(population: list[tuple[int, int]]) -> dict[int, int]: | |
living_per_year = {} | |
for birth, death in population: | |
if birth in living_per_year: | |
living_per_year[birth] += 1 | |
else: | |
living_per_year[birth] = 1 | |
if death in living_per_year: | |
living_per_year[death] -= 1 | |
else: | |
living_per_year[death] = -1 | |
for year in range(min(living_per_year), max(living_per_year)): | |
living_per_year[year] += living_per_year.get(year - 1, 0) | |
living_per_year.pop(max(living_per_year)) | |
return living_per_year | |
print(sorted(tuple(count_living_per_year(pop).items()))) | |
print( | |
timeit.timeit( | |
"count_living_per_year(pop)", | |
globals=globals(), | |
number=100, | |
) | |
) | |
# 0.118 s (with 10000 people [1,100] years old) | |
def count_living_per_year(population: list[tuple[int, int]]) -> dict[int, int]: | |
living_per_year = collections.defaultdict(int) | |
for birth, death in population: | |
living_per_year[birth] += 1 | |
living_per_year[death] -= 1 | |
min_, max_ = min(living_per_year), max(living_per_year) | |
for year in range(min_, max_): | |
living_per_year[year] += living_per_year[year - 1] | |
del living_per_year[min_ - 1], living_per_year[max_] | |
return living_per_year | |
print(sorted(tuple(count_living_per_year(pop).items()))) | |
print( | |
timeit.timeit( | |
"count_living_per_year(pop)", | |
globals=globals(), | |
number=100, | |
) | |
) | |
# 0.105 s (with 10000 people [1,100] years old) | |
def count_living_per_year(population: list[tuple[int, int]]) -> dict[int, int]: | |
births = collections.Counter(birth for birth, _ in population) | |
deaths = collections.Counter(death for _, death in population) | |
living_per_year = births | |
for year in range(min(births), max(deaths)): | |
living_per_year[year] += living_per_year[year - 1] - deaths[year] | |
return living_per_year | |
print(sorted(tuple(count_living_per_year(pop).items()))) | |
print( | |
timeit.timeit( | |
"count_living_per_year(pop)", | |
globals=globals(), | |
number=100, | |
) | |
) | |
# 0.108 s (with 10000 people [1,100] years old) | |
def count_living_per_year(population: list[tuple[int, int]]) -> dict[int, int]: | |
births = collections.Counter(birth for birth, _ in population) | |
deaths = collections.Counter(death for _, death in population) | |
(delta_per_year := births).subtract(deaths) | |
living_per_year = collections.Counter() | |
for year in range(min(delta_per_year), max(delta_per_year)): | |
living_per_year[year] = living_per_year[year - 1] + delta_per_year[year] | |
return living_per_year | |
print(sorted(tuple(count_living_per_year(pop).items()))) | |
print( | |
timeit.timeit( | |
"count_living_per_year(pop)", | |
globals=globals(), | |
number=100, | |
) | |
) | |
# 0.093 s (with 10000 people [1,100] years old) | |
def count_living_per_year(population: list[tuple[int, int]]) -> dict[int, int]: | |
births, deaths = zip(*population) | |
births_counter = collections.Counter(births) | |
deaths_counter = collections.Counter(deaths) | |
living_per_year = collections.Counter() | |
for year in range(min(births_counter), max(deaths_counter)): | |
delta_living = births_counter[year] - deaths_counter[year] | |
living_per_year[year] = living_per_year[year - 1] + delta_living | |
return living_per_year | |
print(sorted(tuple(count_living_per_year(pop).items()))) | |
print( | |
timeit.timeit( | |
"count_living_per_year(pop)", | |
globals=globals(), | |
number=100, | |
) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment