AtCoder ABC155 Problem D Pairs Review Note 2 NumPy and Python

Overview

A note about AtCoder ABC155 Problem D Pairs.

I measured the speed of Python and NumPy for "sorting" and "dichotomy". Before the implementation, both processes expected NumPy to win overwhelmingly. Sorting is about 10 times faster with NumPy. The dichotomy shows that NumPy is faster when giving a large number of thresholds as a list, but Python is faster than NumPy when calling a function for one threshold. It's quite surprising.

Background

Continuation of AtCoder ABC155 Problem D Pairs Review Note 1. It was observed that the reason why I couldn't get out of TLE with this problem seems to be that Python is slower than NumPy. So I wrote a test program to compare Python and NumPy and measured the speed.

result

(The program used for the measurement is at the bottom)

sort I compared the execution times of sorted (Python) and numpy.sort (NumPy) when I changed the size of List (Python) and Array (NumPy) from 1024 to 1048576. The vertical axis of the graph is the execution time (seconds), and the horizontal axis is the List or Array size. graph-sort-elapsedtime.png

Each measurement was performed 16 times, and the graph shows the average, maximum, and minimum elapsed times. LIST:Python sorted() ARRAY: NumPy numpy.sort() From the result, it can be seen that the processing of Array (NumPy) is almost 10 times faster than the processing of List (Python).

Dichotomy

I compared the execution times of bisect.bisect_left (Python) and numpy.searchsorted (NumPy) when changing the size of List (Python) and Array (NumPy) from 1024 to 1048576. The vertical axis of the graph is the execution time (seconds), and the horizontal axis is the List or Array size. If this function is a problem of the same size, it finishes in a much shorter time than sorting and there is a problem with the measurement system, so 1. Call it 1024 times with a for statement or 2. Give a threshold with 1024 times LIST 1 The implementation time is plotted when the dichotomy is repeated 1024 times per trial.

graph-bisect-elapsedtime.png

LIST: Python bisect.bisect_left () Called 1024 times with for statement ARRAY: Call 1024 times with NumPy numpy.searchsorted () for statement ARRAY2: NumPy numpy.searchsorted () Call once with a list of size 1024 passed as the second argument

Each measurement was performed 16 times, and the graph shows the average, maximum, and minimum elapsed times. The Array uses a for statement to call numpy.searchsorted () 1024 times per attempt. Array2 performs the same processing per trial by giving a list of size 1024 to the second argument of numpy.searchsorted ().

From the result, the performance is better in the order of Array2 (NumPy), List (Python), Array (NumPy). The performance difference tends to shrink as the size increases. However, even with size 1048576, Array2 (NumPy) is several times better than others. It was a bit surprising that Python bisect.bisect_left () seemed to perform better than NumPy numpy.searchsorted () when no list was used as the second argument.

Impressions

From this speed difference, I couldn't TLE my program in AtCoder ABC155 Problem D Pairs because I didn't use NumPy. It is inferred that. There are many things I have to remember. I would like to try a C ++ test with the same question for practice if I have the opportunity.

Appedix Program used for testing

python:random.bisect.py


import math
import sys
import numpy as np
import random
import time
import bisect

args = sys.argv
stdin = sys.stdin
rangeMax = 2 ** 60
n_bisect_try = 1024
target = [random.randrange(0,rangeMax) for _ in range(n_bisect_try)]

print(rangeMax) 
N = int(args[1])

def start_time():
    global start
    start = time.time()

def end_time(header="Elapsed time: "):
    global start
    elapsed_time = time.time() - start
    print("{0}{1:0.7f}".format(header,elapsed_time))
    return elapsed_time

start_time()
s = [ random.randrange(0,rangeMax) for _ in range(N)]
end_time('Time Generate Random List: ')
# print(s)    

start_time()
sn = np.array(s)
end_time('Time Make Array: ')


start_time()
s_sort = sorted(s)
end_time("Time List Sort: ")
#print(s,s_sort)

start_time()
for t in target:
    i  = bisect.bisect_left(s_sort,t)
    #print("Result List Bisect:", i)
end_time("Time List Bisect: ")

start_time()
sn_sort = np.sort(sn)
end_time("Time Array Sort: ")
# print(sn,sn_sort)

start_time()
for t in target:
    i  = np.searchsorted(sn_sort,t)
    # print("Result List Bisect:", i)
end_time("Time Array Bisect: ")

start_time()
i_array  = np.searchsorted(sn_sort,target)
#print("Result List Bisect2:", i_array)
end_time("Time Array Bisect2: ")

Recommended Posts

AtCoder ABC155 Problem D Pairs Review Note 2 NumPy and Python
AtCoder ABC155 Problem D Pairs Review Note 1
AtCoder ABC 182 Python (A ~ D)
Solving with Ruby and Python AtCoder ABC178 D Dynamic programming
Solving with Ruby and Python AtCoder ABC151 D Breadth-first search
Solve with Ruby and Python AtCoder ABC133 D Cumulative sum
AtCoder ABC151 Problem D Speed comparison in C ++ / Python / PyPy
AtCoder ABC156 Problem D Bouquet mod calculation and permutations, etc.
Solving with Ruby and Python AtCoder ABC138 D Adjacency list
Solving in Ruby, Python and Java AtCoder ABC141 D Priority Queuing
Solving with Ruby, Python and numpy AtCoder ABC054 B Matrix operation
Solving with Ruby, Python and networkx AtCoder ABC168 D Adjacency list
Python beginner Atcoder memo @ KEYENCE 2020, ABC problem
[AtCoder] Solve ABC1 ~ 100 A problem with Python
Solve AtCoder ABC168 with python (A ~ D)
AtCoder ABC 174 Python
AtCoder ABC187 Python
AtCoder ABC188 Python
AtCoder ABC 175 Python
AtCoder ABC130 D Cumulative Sum Binary Search Solved by Ruby and Python
Solving with Ruby, Perl, Java and Python AtCoder ABC 165 D Floor function
Solving with Ruby, Perl, Java and Python AtCoder ABC 131 D Array Sorting
[AtCoder] Solve A problem of ABC101 ~ 169 with Python
Challenge AtCoder (ABC) 164 with Python! A ~ C problem
Solve with Ruby and Python AtCoder ABC084 D Cumulative sum of prime numbers
Python and numpy tips
AtCoder ARC080 D simulation solved in Ruby and Python
Review of atcoder ABC158, up to question E (Python)
AtCoder ABC 177 Python (A ~ E)
Solve AtCoder ABC166 with python
ABC163 C problem with python3
AtCoder ABC 178 Python (A ~ E)
Atcoder ABC164 A-C in Python
Python Input Note in AtCoder
AtCoder ABC 176 Python (A ~ E)
Atcoder ABC167 A-D in Python
Solving with Ruby and Python AtCoder AISING2020 D Iterative Squares
Solve ABC175 D in Python
Atcoder ABC165 A-D in Python
Solving with Ruby and Python AtCoder ABC011 C Dynamic programming
Solving with Ruby and Python AtCoder ABC153 E Dynamic programming
Atcoder ABC166 A-E in Python
[AtCoder] ABC165C Personal Note [Python]
ABC188 C problem with python3
Solve AtCoder ABC 186 with Python
AtCoder ABC168 A case expression solved in Ruby and Python
ABC187 C problem with python
Atcoder ABC169 A-E in Python
AtCoder ABC177 A-D in python
[AtCoder commentary] Win the ABC165 C problem "Many Requirements" with Python!
I wanted to solve the ABC164 A ~ D problem with Python
Solving with Ruby, Perl, Java, and Python AtCoder ABC 065 C factorial
[Note] Project Euler in Python (Problem 1-22)
Solve ABC166 A ~ D with Python
ABC166 in Python A ~ C problem
Solve Atcoder ABC169 A-D in Python
Solved AtCoder ABC 114 C-755 with Python3
Template AtCoder ABC 179 Python (A ~ E)
AtCoder Beginner Contest 174 C Problem (Python)
Solving with Ruby and Python AtCoder ABC057 C Prime Factorization Bit Search
Solving with Ruby, Perl, Java and Python AtCoder ABC 107 B String Manipulation