Skip to content

Commit 711ee5e

Browse files
authored
Merge pull request #59 from codeflash-ai/codeflash-trace-decorator
Codeflash trace decorator
2 parents 1585e4b + 683c9f6 commit 711ee5e

File tree

53 files changed

+3754
-70
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+3754
-70
lines changed

.github/workflows/codeflash-optimize.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,4 @@ jobs:
6868
id: optimize_code
6969
run: |
7070
source .venv/bin/activate
71-
poetry run codeflash
71+
poetry run codeflash --benchmark
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: end-to-end-test
2+
3+
on:
4+
pull_request:
5+
workflow_dispatch:
6+
7+
jobs:
8+
benchmark-bubble-sort-optimization:
9+
runs-on: ubuntu-latest
10+
env:
11+
CODEFLASH_AIS_SERVER: prod
12+
POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }}
13+
CODEFLASH_API_KEY: ${{ secrets.CODEFLASH_API_KEY }}
14+
COLUMNS: 110
15+
MAX_RETRIES: 3
16+
RETRY_DELAY: 5
17+
EXPECTED_IMPROVEMENT_PCT: 5
18+
CODEFLASH_END_TO_END: 1
19+
steps:
20+
- uses: actions/checkout@v4
21+
with:
22+
fetch-depth: 0
23+
token: ${{ secrets.GITHUB_TOKEN }}
24+
25+
- name: Set up Python 3.11 for CLI
26+
uses: astral-sh/setup-uv@v5
27+
with:
28+
python-version: 3.11.6
29+
30+
- name: Install dependencies (CLI)
31+
run: |
32+
uv tool install poetry
33+
uv venv
34+
source .venv/bin/activate
35+
poetry install --with dev
36+
37+
- name: Run Codeflash to optimize code
38+
id: optimize_code_with_benchmarks
39+
run: |
40+
source .venv/bin/activate
41+
poetry run python tests/scripts/end_to_end_test_benchmark_sort.py

.github/workflows/unit-tests.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
run: uvx poetry install --with dev
3333

3434
- name: Unit tests
35-
run: uvx poetry run pytest tests/ --cov --cov-report=xml
35+
run: uvx poetry run pytest tests/ --cov --cov-report=xml --benchmark-skip -m "not ci_skip"
3636

3737
- name: Upload coverage reports to Codecov
3838
uses: codecov/codecov-action@v5

code_to_optimize/bubble_sort.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ def sorter(arr):
77
arr[j] = arr[j + 1]
88
arr[j + 1] = temp
99
print(f"result: {arr}")
10-
return arr
10+
return arr
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
from codeflash.benchmarking.codeflash_trace import codeflash_trace
2+
@codeflash_trace
3+
def sorter(arr):
4+
for i in range(len(arr)):
5+
for j in range(len(arr) - 1):
6+
if arr[j] > arr[j + 1]:
7+
temp = arr[j]
8+
arr[j] = arr[j + 1]
9+
arr[j + 1] = temp
10+
return arr
11+
12+
@codeflash_trace
13+
def recursive_bubble_sort(arr, n=None):
14+
# Initialize n if not provided
15+
if n is None:
16+
n = len(arr)
17+
18+
# Base case: if n is 1, the array is already sorted
19+
if n == 1:
20+
return arr
21+
22+
# One pass of bubble sort - move the largest element to the end
23+
for i in range(n - 1):
24+
if arr[i] > arr[i + 1]:
25+
arr[i], arr[i + 1] = arr[i + 1], arr[i]
26+
27+
# Recursively sort the remaining n-1 elements
28+
return recursive_bubble_sort(arr, n - 1)
29+
30+
class Sorter:
31+
@codeflash_trace
32+
def __init__(self, arr):
33+
self.arr = arr
34+
@codeflash_trace
35+
def sorter(self, multiplier):
36+
for i in range(len(self.arr)):
37+
for j in range(len(self.arr) - 1):
38+
if self.arr[j] > self.arr[j + 1]:
39+
temp = self.arr[j]
40+
self.arr[j] = self.arr[j + 1]
41+
self.arr[j + 1] = temp
42+
return self.arr * multiplier
43+
44+
@staticmethod
45+
@codeflash_trace
46+
def sort_static(arr):
47+
for i in range(len(arr)):
48+
for j in range(len(arr) - 1):
49+
if arr[j] > arr[j + 1]:
50+
temp = arr[j]
51+
arr[j] = arr[j + 1]
52+
arr[j + 1] = temp
53+
return arr
54+
55+
@classmethod
56+
@codeflash_trace
57+
def sort_class(cls, arr):
58+
for i in range(len(arr)):
59+
for j in range(len(arr) - 1):
60+
if arr[j] > arr[j + 1]:
61+
temp = arr[j]
62+
arr[j] = arr[j + 1]
63+
arr[j + 1] = temp
64+
return arr
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# from code_to_optimize.bubble_sort_codeflash_trace import sorter
2+
from code_to_optimize.bubble_sort_codeflash_trace import sorter
3+
import concurrent.futures
4+
5+
6+
def multithreaded_sorter(unsorted_lists: list[list[int]]) -> list[list[int]]:
7+
# Create a list to store results in the correct order
8+
sorted_lists = [None] * len(unsorted_lists)
9+
10+
# Use ThreadPoolExecutor to manage threads
11+
with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
12+
# Submit all sorting tasks and map them to their original indices
13+
future_to_index = {
14+
executor.submit(sorter, unsorted_list): i
15+
for i, unsorted_list in enumerate(unsorted_lists)
16+
}
17+
18+
# Collect results as they complete
19+
for future in concurrent.futures.as_completed(future_to_index):
20+
index = future_to_index[future]
21+
sorted_lists[index] = future.result()
22+
23+
return sorted_lists
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
from codeflash.benchmarking.codeflash_trace import codeflash_trace
3+
4+
5+
@codeflash_trace
6+
def bubble_sort_with_unused_socket(data_container):
7+
# Extract the list to sort, leaving the socket untouched
8+
numbers = data_container.get('numbers', []).copy()
9+
10+
return sorted(numbers)
11+
12+
@codeflash_trace
13+
def bubble_sort_with_used_socket(data_container):
14+
# Extract the list to sort, leaving the socket untouched
15+
numbers = data_container.get('numbers', []).copy()
16+
socket = data_container.get('socket')
17+
socket.send("Hello from the optimized function!")
18+
return sorted(numbers)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from codeflash.benchmarking.codeflash_trace import codeflash_trace
2+
3+
@codeflash_trace
4+
def bubble_sort_with_used_socket(data_container):
5+
"""
6+
Performs a bubble sort on a list within the data_container. The data container has the following schema:
7+
- 'numbers' (list): The list to be sorted.
8+
- 'socket' (socket): A socket
9+
10+
Args:
11+
data_container: A dictionary with at least 'numbers' (list) and 'socket' keys
12+
13+
Returns:
14+
list: The sorted list of numbers
15+
"""
16+
# Extract the list to sort and socket
17+
numbers = data_container.get('numbers', []).copy()
18+
socket = data_container.get('socket')
19+
20+
# Track swap count
21+
swap_count = 0
22+
23+
# Classic bubble sort implementation
24+
n = len(numbers)
25+
for i in range(n):
26+
# Flag to optimize by detecting if no swaps occurred
27+
swapped = False
28+
29+
# Last i elements are already in place
30+
for j in range(0, n - i - 1):
31+
# Swap if the element is greater than the next element
32+
if numbers[j] > numbers[j + 1]:
33+
# Perform the swap
34+
numbers[j], numbers[j + 1] = numbers[j + 1], numbers[j]
35+
swapped = True
36+
swap_count += 1
37+
38+
# If no swapping occurred in this pass, the list is sorted
39+
if not swapped:
40+
break
41+
42+
# Send final summary
43+
summary = f"Bubble sort completed with {swap_count} swaps"
44+
socket.send(summary.encode())
45+
46+
return numbers
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from code_to_optimize.bubble_sort import sorter
2+
3+
4+
def calculate_pairwise_products(arr):
5+
"""
6+
Calculate the average of all pairwise products in the array.
7+
"""
8+
sum_of_products = 0
9+
count = 0
10+
11+
for i in range(len(arr)):
12+
for j in range(len(arr)):
13+
if i != j:
14+
sum_of_products += arr[i] * arr[j]
15+
count += 1
16+
17+
# The average of all pairwise products
18+
return sum_of_products / count if count > 0 else 0
19+
20+
21+
def compute_and_sort(arr):
22+
# Compute pairwise sums average
23+
pairwise_average = calculate_pairwise_products(arr)
24+
25+
# Call sorter function
26+
sorter(arr.copy())
27+
28+
return pairwise_average
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from code_to_optimize.bubble_sort import sorter
2+
from codeflash.benchmarking.codeflash_trace import codeflash_trace
3+
4+
def calculate_pairwise_products(arr):
5+
"""
6+
Calculate the average of all pairwise products in the array.
7+
"""
8+
sum_of_products = 0
9+
count = 0
10+
11+
for i in range(len(arr)):
12+
for j in range(len(arr)):
13+
if i != j:
14+
sum_of_products += arr[i] * arr[j]
15+
count += 1
16+
17+
# The average of all pairwise products
18+
return sum_of_products / count if count > 0 else 0
19+
20+
@codeflash_trace
21+
def compute_and_sort(arr):
22+
# Compute pairwise sums average
23+
pairwise_average = calculate_pairwise_products(arr)
24+
25+
# Call sorter function
26+
sorter(arr.copy())
27+
28+
return pairwise_average

0 commit comments

Comments
 (0)