logo
Menu
Unleash Amazon Q Developer: From Code Creation to Legacy Code optimization (Part 2)

Unleash Amazon Q Developer: From Code Creation to Legacy Code optimization (Part 2)

The post, part of a series, chronicles the author's experience optimizing legacy S3 bucket listing code using Amazon Q Developer through three rounds of interactions. Despite initial bugs, Amazon Q's suggestions, like reducing API calls and using list comprehensions, ultimately led to fully runnable optimized code with 150% better performance, highlighting the Amazon Q Developer's value in iterative legacy code optimization.

Haowen Huang
Amazon Employee
Published May 25, 2024

Overview

In the previous blog post, we demonstrated how to utilize Amazon Q Developer within Visual Studio Code to optimize legacy code. As we discussed in the "Optimizing Legacy Code" section, transforming legacy code into a high-performance version is an iterative process.
For the specified S3 bucket list function legacy code, it took three rounds of detailed communication and interaction with Amazon Q Developer before achieving the optimized code that met my expectations. We'll dive deep into the three rounds of communication and interaction.

First Interaction with Amazon Q

The Prompt I Sent to the Amazon Q chat panel was:
“Please carefully review the code I have written. While preserving the required functionality of the code, please optimize my code, for example: provide alternative implementations that improve time or memory efficiency. Your feedback and guidance will be extremely valuable for improving my programming abilities. If you need any other background information or explanations regarding the code, please let me know. Finally, please provide the complete runnable code in its entirety.”
Amazon Q’s response is shown in the following two screenshots:
First Interaction with Amazon Q - #1
First Interaction with Amazon Q - #1
First Interaction with Amazon Q - #2
First Interaction with Amazon Q - #2
To facilitate reading for the readers, I have copied the content of the above screenshots into text as follows:
“I'm Amazon Q, an AI assistant created by Amazon to help you with your programming tasks.
Regarding the code you provided, it appears to be a Python script that interacts with the AWS S3 service to list the S3 buckets in the 'ap-east-1' region and record the execution time of the script. The code seems to be functional and achieve the required functionality.
To optimize the code for better time and memory efficiency, here are a few suggestions: [1]
1. Reduce the number of API calls: The current implementation makes two API calls to the S3 service - one to list all the buckets, and another to get the location constraint for each bucket. You can optimize this by making a single API call to list_buckets() and then filtering the results to get the buckets in the 'ap-east-1' region. This will reduce the number of API calls and improve the overall performance.
(The generated code part is omitted)
2. Use a list comprehension instead of a for loop: The current implementation uses a for loop to iterate over the bucket names and print them. You can simplify this by using a list comprehension, which is more concise and efficient.
(The generated code part is omitted)
3. Avoid unnecessary imports: The current implementation imports several modules that are not used in the main function. You can remove the unused imports to improve the readability and maintainability of the code.
4. Consider using the AWS CDK library: Since you're already using the AWS CDK library, you could explore further optimizations by leveraging its features and capabilities. For example, you could use the CfnOutput construct to output the list of bucket names directly, without the need for a separate loop.
(The generated code part is omitted)
These optimizations should help improve the time and memory efficiency of your code. If you have any further questions or need additional assistance, please feel free to ask.”

Analysis Summary

According to the initial response from Amazon Q, the code is functional but can be optimized for better time and memory efficiency. The recommendations include reducing the number of API calls by making a single call to `list_buckets()` and filtering the results, using a list comprehension instead of a `for` loop for conciseness, removing unnecessary imports, and considering the AWS CDK library for further optimizations, such as directly outputting bucket names without a separate loop.
While Amazon Q's analysis seems reasonable, the most crucial aspect for us as programmers is that the code must be executable. Unfortunately, the code output by Amazon Q in the first round could not run directly, and I didn't want to spend dozens of significant amounts of time debugging the generated code. I hoped it would immediately provide me with a runnable solution.
Consequently, the following is the second round of interaction with Amazon Q.

Second Interaction with Amazon Q

Prompt sent to Amazon Q:
“Please provide the complete code you suggested above, it needs to be fully runnable.”
 
Second Interaction with Amazon Q - #1
Second Interaction with Amazon Q - #1
Second Interaction with Amazon Q - #2
Second Interaction with Amazon Q - #2
To facilitate reading for the readers, I have copied the content of the above screenshots into text as follows:
“Here's the complete, runnable code with the optimizations I suggested:
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
import time
from aws_cdk import (
App, Stack, CfnOutput
)
import boto3

class MyStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)

s3_client = boto3.client('s3', region_name='ap-east-1')
response = s3_client.list_buckets()
ap_east_1_buckets = [bucket['Name'] for bucket in response['Buckets'] if bucket['Region'] == 'ap-east-1']

print(f"Number of buckets found in ap-east-1 region: {len(ap_east_1_buckets)}")
print("\nBucket names:")
print('\n'.join(ap_east_1_buckets))

for i, bucket_name in enumerate(ap_east_1_buckets):
CfnOutput(self, f"Bucket-{i}", value=bucket_name)

def main():
start_time = time.time()
app = App()
MyStack(app, "haowen-cdk-app-list-S3-demo")
app.synth()
end_time = time.time()
execution_time = end_time - start_time
print(f"\nTotal execution time: {execution_time} seconds")

if __name__ == "__main__":
main()
You can install them using pip:
1
pip install aws-cdk-lib boto3
Then, you can run the script using the following command:
1
python s3-demo-1.py
This should output the number of buckets found in the 'ap-east-1' region, the list of bucket names, and the total execution time of the script.”

Analysis Summary

This time, Amazon Q outputted the full code. The optimizations seemed to include reducing API calls, using list comprehension, removing unused imports, and leveraging the AWS CDK library for output. Overall, the code appeared well-written and effectively achieved its intended purpose.
However, after the second round of interaction, the code I obtained still had some errors when running it. Consequently, I requested that Amazon Q fix the bugs in the code it had suggested.

Third Interaction with Amazon Q

Prompt sent to Amazon Q:
“When run your above code, I get the following error message:
File "/Users/AMAZON/haowen-demo/q-dev/s3-demo-1-qrevised-1.py", line 20, in apeast1_buckets = [bucket['Name'] for bucket in response['Buckets'] if bucket['Region'] == 'ap-east-1'] KeyError: 'Region'”
Third Interaction with Amazon Q - #1
Third Interaction with Amazon Q - #1
To facilitate reading for the readers, I have copied the content of the above screenshots into text as follows:
“I apologize for the oversight. The issue is that the listbuckets() API call does not return the Region information for each bucket. To work around this, we can use the getbucket_location() API call to get the region for each bucket, similar to the original code.
Here's the updated, fully runnable code:
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
import time
from aws_cdk import (
App, Stack, CfnOutput
)
import boto3
from constructs import Construct

class MyStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)

s3_client = boto3.client('s3', region_name='ap-east-1')
response = s3_client.list_buckets()
ap_east_1_buckets = []

for bucket in response['Buckets']:
bucket_region = s3_client.get_bucket_location(Bucket=bucket['Name'])['LocationConstraint']
if bucket_region == 'ap-east-1':
ap_east_1_buckets.append(bucket['Name'])

print(f"Number of buckets found in ap-east-1 region: {len(ap_east_1_buckets)}")
print("\nBucket names:")
print('\n'.join(ap_east_1_buckets))

for i, bucket_name in enumerate(ap_east_1_buckets):
CfnOutput(self, f"Bucket-{i}", value=bucket_name)

def main():
start_time = time.time()
app = App()
MyStack(app, "haowen-cdk-app-list-S3-demo")
app.synth()
end_time = time.time()
execution_time = end_time - start_time
print(f"\nTotal execution time: {execution_time} seconds")

if __name__ == "__main__":
main()
The main changes are:
Instead of using a list comprehension to filter the buckets, we're iterating over the Buckets list and using the getbucketlocation() API call to determine the region for each bucket.
If the bucket is in the 'ap-east-1' region, we add it to the apeast1_buckets list.
This should resolve the KeyError: 'Region' issue you were encountering. Please let me know if you have any other questions or if you need further assistance.”

Analysis Summary

This code is the optimized version we introduced in the previous blog post that finally ran successfully. As demonstrated by the screenshot in the prior post, the execution time of this optimized code is only 1.7 seconds, outperforming the legacy code which took 4.3 seconds to run - a remarkable 150% performance improvement!
Running result of the optimized code by Amazon Q Developer
Running result of the optimized code by Amazon Q Developer
The complete three-round iterative process communicating with Amazon Q Developer ultimately helped enhance the code's execution efficiency by over 150%. This exemplifies the power of Amazon Q as an AI coding collaborator to substantially optimize legacy code performance.

Wrapping up

In this follow-up post, I chronicled my experience optimizing legacy S3 bucket listing code using Amazon Q Developer across three rounds of interaction. Initially, Amazon Q provided suggestions like reducing API calls, utilizing list comprehensions, and leveraging the AWS CDK library. However, the first batch of optimized code generated could not run successfully.
After requesting fully runnable code, Amazon Q provided an updated version incorporating the previous optimizations. While more refined, this second attempt still contained bugs, prompting a third round of clarification.
Ultimately, Amazon Q debugged the issues by reverting to the original approach of using ‘get_bucket_location()’ to determine each bucket's region before filtering for the desired 'ap-east-1' location. This fully executable optimized code achieved over 150% better performance compared to the original legacy implementation.
Through this iterative process spanning multiple rounds of detailed communication with Amazon Q Developer, I successfully transformed the legacy code into an optimized high-performance version. The experience highlights Amazon Q's value as a collaborative AI coding companion capable of incrementally refining and perfecting code optimization efforts through an iterative process!
Note: The cover image for this blog post was generated using the SDXL 1.0 model on Amazon Bedrock. The prompt given was as follows:
The style should be a blend of realism and abstract elements. comic, graphic illustration, comic art, graphic novel art, vibrant, highly detailed, colored, 2d minimalistic. An artistic digital render depicting a beautiful girl coding on a laptop, with lines of code and symbols swirling around them. The background should have a futuristic, tech-inspired design with shades of blue and orange. The overall image should convey the themes of code optimization, legacy code, and the power of Amazon Q Developer's AI assistance.
 

Any opinions in this post are those of the individual author and may not reflect the opinions of AWS.

Comments