I want to compare the effect of multiprocessing for bubble sort.
Let us consider first the original one without multiprocessing:
import multiprocessing
import random
import time
import numpy as np
def bubble_sort(array):
check = True
while check == True:
check = False
for i in range(len(array) - 1):
if array[i] > array[i + 1]:
check = True
temp = array[i]
array[i] = array[i + 1]
array[i + 1] = temp
print("Array sorted: ", array)
if __name__ == "__main__":
array = np.random.randint(0, 1000, 10000)
start = time.time()
bubble_sort(array)
print("Time taken: ", time.time() - start)
The result is:
Array sorted: [ 0 0 0 ... 999 999 999]
Time taken: 25.157966375350952
Now with multiprocessing:
if __name__ == "__main__":
array = np.random.randint(0, 1000, 10000)
p = multiprocessing.Process(target=bubble_sort, args=(array,))
start = time.time()
p.start()
p.join()
print("Time taken: ",time.time()-start)
The result is:
Array sorted: [ 0 0 0 ... 999 999 999]
Time taken: 24.962100744247437
There is only one second difference, am I missing something?
You are not doing multiprocessing in your code. Try this code to see the difference
import multiprocessing
import numpy as np
import time
import copy
def bubble_sort(array):
n = len(array)
for i in range(n):
for j in range(0, n - i - 1):
if array[j] > array[j + 1]:
array[j], array[j + 1] = array[j + 1], array[j]
return array
def merge_chunks(left, right):
merged = []
left_index = 0
right_index = 0
while left_index < len(left) and right_index < len(right):
if left[left_index] <= right[right_index]:
merged.append(left[left_index])
left_index += 1
else:
merged.append(right[right_index])
right_index += 1
merged.extend(left[left_index:])
merged.extend(right[right_index:])
return merged
def parallel_bubble_sort(array):
num_processes = multiprocessing.cpu_count() # Use all available cores
chunk_size = (len(array) + num_processes - 1) // num_processes
pool = multiprocessing.Pool(processes=num_processes)
chunks = []
start = 0
for i in range(num_processes):
end = min((i + 1) * chunk_size, len(array))
chunks.append(array[start:end])
start = end
results = pool.map(bubble_sort, chunks)
pool.close()
pool.join()
# Merge the sorted chunks
while len(results) > 1:
new_results = []
for i in range(0, len(results), 2):
if i + 1 < len(results):
merged_chunk = merge_chunks(results[i], results[i+1])
new_results.append(merged_chunk)
else:
new_results.append(results[i])
results = new_results
return results[0]
if __name__ == "__main__":
array_size = 10000
array = np.random.randint(0, 1000, array_size).tolist()
array_copy = copy.deepcopy(array)
start_time = time.perf_counter()
sorted_array = bubble_sort(array)
end_time = time.perf_counter()
print("Bubble sort without multiprocessing: ", end_time - start_time)
start_time = time.perf_counter()
sorted_array = parallel_bubble_sort(array_copy)
end_time = time.perf_counter()
print("Bubble sort with multiprocessing: ", end_time - start_time)
I split the array into chunks and gave each chunk to a processor core to be sorted. Then I merged the sorted chunks, ensuring the merged chunks are ordered, and get this results.
Bubble sort without multiprocessing: 17.12360268399061
Bubble sort with multiprocessing: 1.380762806002167