-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRvJuliavPython.qmd
More file actions
154 lines (117 loc) · 3.39 KB
/
Copy pathRvJuliavPython.qmd
File metadata and controls
154 lines (117 loc) · 3.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
---
title: "Untitled"
format: html
---
```{python}
# Python - Fair comparison
import time
import threading
import numpy as np
def sum_of_squares_sequential(arr):
total = 0.0
for i in arr:
total += i * i
return total
def sum_of_squares_parallel(arr):
def compute_chunk(start_idx, end_idx):
return sum(arr[i] * arr[i] for i in range(start_idx, end_idx))
n_threads = min(4, len(arr) // 10000)
if n_threads <= 1:
return sum_of_squares_sequential(arr)
chunk_size = len(arr) // n_threads
threads = []
results = [0.0] * n_threads
def thread_worker(thread_id):
start_idx = thread_id * chunk_size
end_idx = start_idx + chunk_size if thread_id < n_threads - 1 else len(arr)
results[thread_id] = compute_chunk(start_idx, end_idx)
for i in range(n_threads):
t = threading.Thread(target=thread_worker, args=(i,))
threads.append(t)
t.start()
for t in threads:
t.join()
return sum(results)
# Same data size as R and Julia
data = np.random.rand(1000000).tolist()
# Benchmark multiple times for consistency
times = []
for _ in range(10):
start = time.time()
result = sum_of_squares_sequential(data)
times.append(time.time() - start)
seq_time = np.mean(times)
print(f"Python Sequential: {seq_time:.6f} seconds")
times = []
for _ in range(10):
start = time.time()
result = sum_of_squares_parallel(data)
times.append(time.time() - start)
par_time = np.mean(times)
print(f"Python Parallel: {par_time:.6f} seconds")
print(f"Speedup: {seq_time/par_time:.2f}x")
```
```{julia}
# Julia - Fair comparison
using BenchmarkTools
using Base.Threads
function sum_of_squares_sequential(arr)
total = 0.0
for i in arr
total += i * i
end
return total
end
function sum_of_squares_parallel(arr)
total = 0.0
@threads for i in arr
total += i * i
end
return total
end
# Same data size as Python and R
data = rand(1000000)
# Benchmark with same number of runs
println("Julia Sequential:")
seq_result = @benchmark sum_of_squares_sequential($data) samples=10
println("Julia Parallel:")
par_result = @benchmark sum_of_squares_parallel($data) samples=10
println("Sequential time: $(minimum(seq_result.times)/1e6) ms")
println("Parallel time: $(minimum(par_result.times)/1e6) ms")
```
```{r}
# R - Fair comparison
library(microbenchmark)
library(parallel)
sum_of_squares_sequential <- function(arr) {
total <- 0.0
for (i in arr) {
total <- total + i * i
}
return(total)
}
sum_of_squares_parallel <- function(arr) {
n_cores <- detectCores() - 1
chunk_size <- length(arr) %/% n_cores
chunks <- split(arr, rep(1:n_cores, each = chunk_size, length.out = length(arr)))
results <- mclapply(chunks, function(chunk) sum(chunk^2), mc.cores = n_cores)
return(sum(unlist(results)))
}
# Same data size as Python and Julia
data <- runif(1000000)
# Benchmark with same number of runs
seq_result <- microbenchmark(
sum_of_squares_sequential(data),
times = 10
)
par_result <- microbenchmark(
sum_of_squares_parallel(data),
times = 10
)
# Print average times
seq_avg <- mean(seq_result$time) / 1e6 # Convert to milliseconds
par_avg <- mean(par_result$time) / 1e6
print(paste("R Sequential:", round(seq_avg, 4), "ms"))
print(paste("R Parallel:", round(par_avg, 4), "ms"))
print(paste("Speedup:", round(seq_avg/par_avg, 2), "x"))
```