本文将探索如何在 Visual Studio Code 这个开发者常用的一种集成编程环境(IDE)中,使用 Amazon Q Developer 列出指定区域的 Amazon S3 存储桶的示例代码实现。我们将从在 Amazon Q Developer Agent 的协助下,从生成新代码开始,到将生成的新代码与现有的低效“遗留”旧代码进行性能对比;然后借助 Amazon Q Developer 的指导,来优化这段遗留代码,从而减少代码执行时间和提升代码效率。
亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里有技术文档、开发案例、技术专栏、培训视频、活动与竞赛等。帮助中国开发者对接世界最前沿技术,观点,和项目,并将中国优秀开发者或技术推荐给全球云社区。如果你还没有关注/收藏,看到这里请一定不要匆匆划过,点这里让它成为你的技术宝库!
特别说明:本文内容选自作者黄浩文本人于 2024 年 5 月,在 Amazon Web Services 开发者社区上发表的原创英文技术博客“Unleash Amazon Q Developer: From Code Creation to Legacy Code Optimization (Part 1)”。在运行于 Amazon Bedrock 的 Claude 3 Sonnet v1 大模型的辅助下,将英文版翻译为该简体中文版。全文略有修改。
原英文博客文章链接如下,供参考:
Community | Unleash Amazon Q Developer: From Code Creation to Legacy Code Optimization (Part 1)
概览
如您所知,亚马逊云科技最近宣布了 Amazon Q Developer 的正式公开可用,这是一款由生成式 AI 驱动的编程助手,可重塑开发者在整个软件开发生命周期(SDLC: Software Development Lifecycle)的开发体验。
官方博客参考如下:
Amazon Q Developer is now generally available
Amazon Q Developer 可帮助开发者更好地理解、构建、扩展和操作 Amazon Web Services 应用程序。您可以询问有关基础设施架构、服务资源、行业最佳实践、参考文档、技术支持等多方面的问题。Amazon Q 还在不断地更新其更广泛的功能,以支持开发者的问题持续获得最新相关且可操作的解答和建议。
在这篇文章中,我们将探讨如何在 Visual Studio Code IDE 环境中使用 Amazon Q Developer 来处理真实世界的编码需求。我们将以编写一段完整有效且高质量的 Python 代码,实现列出某个指定区域中的所有 Amazon S3 存储桶作为演示示例。
在继续阅读之前,建议开发者先参考以下技术文档,了解如何在 Visual Studio Code 中设置 Amazon Q Developer:
What is Amazon Q Developer? - Amazon Q Developer
生成新代码
首先,让我们使用 Amazon Q Developer Agent 来编写初始代码。您可以参考以下文档,了解 Amazon Q Developer Agent 的详细信息:
Develop software with the Amazon Q Developer Agent for software development - Amazon Q Developer
在 Amazon Q Developer Agent 的帮助下编写代码其实比较简单,如下截图所示:
在 Amazon Q Developer 聊天面板中,我使用的提示如下:
/dev Write code to list all the Amazon S3 buckets in the `ap-east-1` region and output their names, along with the total execution time of the script.
翻译成中文,我在提示中对 Amazon Q Developer 的要求是:
“编写代码列出‘ap-east-1’区域中所有的 S3 存储桶的名称,以及计算代码脚本的总执行时间。”
为方便读者参考,我将以上截图中 Amazon Q Developer Agent 生成的代码段复制如下:
import time
import boto3
def list_s3_buckets_in_region(region_name):
"""
Lists all the Amazon S3 buckets in the specified region.
Args:
region_name (str): The AWS region name.
Returns:
list: A list of bucket names.
"""
s3_client = boto3.client('s3', region_name=region_name)
response = s3_client.list_buckets()
buckets = []
for bucket in response['Buckets']:
bucket_region = s3_client.get_bucket_location(Bucket=bucket['Name'])['LocationConstraint']
if bucket_region == region_name:
buckets.append(bucket['Name'])
return buckets
def main():
start_time = time.time()
region_name = 'ap-east-1'
buckets = list_s3_buckets_in_region(region_name)
print(f"Number of buckets found in {region_name} region: {len(buckets)}")
print("\\nBucket names:")
for bucket_name in buckets:
print(bucket_name)
end_time = time.time()
execution_time = end_time - start_time
print(f"\\nTotal execution time: {execution_time:.2f} seconds")
if __name__ == "__main__":
main()
运行以上 Python 代码,将获得如截图所示的运行结果:
哇!仅用了一分钟,Amazon Q Developer Agent 就编写了一个完整的代码列出了我在某个指定区域(ap-east-1, 即中国香港区域)中的 Amazon S3 存储桶,并计算了程序脚本的执行时间。程序总执行时间为 1.37 秒!
与遗留代码的性能对比
我们亲身体验了 Amazon Q Developer 代理快速编写新代码的威力,但它能否帮助我们修改遗留代码呢?作为开发者,在引入 Amazon Q Developer 之前,我们已经编写过大量的遗留代码,我们也同样希望 Amazon Q Developer 能够帮助修改这些大量的遗留代码。
下面这段“遗留”代码,是我自己在没有太多考虑效率和执行速度的情况下编写的。代码的主要功能也是列出某个指定区域中的 Amazon S3 存储桶,输出它们的名称,以及计算脚本的总执行时间。这与我们之前要求 Amazon Q Developer 完成的代码是完全相同的业务需求。
为方便开发者参考,我将自己编写的完整"遗留"代码复制如下:
# The following code counts the number of S3 Buckets in a specified region, lists the names of the S3 Buckets in that region,
# and records the program's execution time.
#
# Author: Haowen Huang
# Date: May 5, 2024
import time
def main():
start_time = time.time() # Record the start time
# Your existing code here
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)
# Create an S3 client for the specific region
s3_client = boto3.client('s3', region_name='ap-east-1')
# Get a list of all buckets in the specific region
all_buckets = []
response = s3_client.list_buckets()
for bucket in response['Buckets']:
bucket_region = s3_client.get_bucket_location(Bucket=bucket['Name'])['LocationConstraint']
if bucket_region == 'ap-east-1':
all_buckets.append(bucket['Name'])
print(f"Number of buckets found in ap-east-1 region: {len(all_buckets)}")
print("\nBucket names:")
for bucket_name in all_buckets:
print(bucket_name)
# Output the list of bucket names
for i, bucket_name in enumerate(all_buckets):
CfnOutput(self, f"Bucket-{i}", value=bucket_name)
app = App()
MyStack(app, "haowen-cdk-app-list-S3-demo")
app.synth()
end_time = time.time() # Record the end time
execution_time = end_time - start_time
print(f"\nTotal execution time: {execution_time} seconds")
if __name__ == "__main__":
main()
运行上述 Python 代码后,将获得如下截图所示的输出:
如上图所示,该段“遗留”代码的总执行时间在 4.33 秒左右,远落后于之前一节中演示的 Amazon Q Developer Agent 生成的代码。
读到这里,你可能会和我当时一样好奇:为什么这段“遗留”代码运行地这么慢?Amazon Q Developer 能否帮助我们诊断出这段运行缓慢的代码的潜在问题,并完成对其的代码优化,从而提升代码运行运行效率呢?我将在下一节为大家揭开这个谜团。
优化遗留代码
首先,我们将“遗留”代码发送给 Amazon Q。将代码发送给 Amazon Q,可参照以下步骤操作:
-
在 IDE 中高亮显示需要发送的代码段,如下所示。
-
右键单击选中的代码段,来打开上下文窗口(context window)。然后选择“Send to Amazon Q”,再选择“Send to prompt”。
Amazon Q 会将选中的代码段复制到Amazon Q聊天面板,在那里你可以输入任何有关该代码的问题或提示。
如下面的屏幕截图所示:
在 Amazon Q 聊天面板中我使用的提示词如下:
“请仔细审阅我编写的代码。在保留代码所需功能的同时,请优化我的代码,例如:提供可提高时间或内存效率的替代实现。你的反馈和指导对于提高我的编程能力将极为宝贵。如果你需要任何其他有关代码的背景信息或解释,请告诉我。最后请提供完整可运行的代码。”
最初 Amazon Q 生成的代码存在一些问题,但经过两轮我和 Amazon Q 的互动交流后,我提供了更多细节和额外的上下文。Amazon Q 最终输出了一个可运行且经过优化的代码,如下截图所示:
为方便各位读者阅读参考,我复制了由 Amazon Q Developer 优化过的完整代码如下:
# The following code counts the number of S3 Buckets in a specified region, lists the names of the S3 Buckets in that region,
# and records the program's execution time.
#
# Revised by Amazon Q Developer
# Date: May 8, 2024
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()
在运行上述 Python 代码后,将得到以下截图所示的输出:
我们很高兴地看到:在采用 Amazon Q Developer 的优化建议后,代码运行时间从原来的 4.33 秒缩短到了 1.7 秒!
那么 Amazon Q Developer 究竟是如何优化这段代码的呢?
实际的优化过程有些波折。在获得这个最终优化并运行完美的代码之前,我和 Amazon Q Developer 其实进行了一共三轮的交互式沟通。篇幅有限,我将在下一篇博客文章中详细介绍这三轮对话沟通的精彩内容。
不过在这里,我还是可以给好奇的开发者们一些提前的剧透。让我们来看看 Amazon Q Developer 发现的主要影响程序执行效率的问题总结。
Amazon Q Developer 发现这段“遗留”代码存在的主要问题输出如下:
“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:
-
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.
-
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.
-
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.
-
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. ……”
我将在下一期的博客中详细解读 Amazon Q Developer 如上的代码优化建议,敬请期待。
总结
Amazon Q Developer 是亚马逊云科技为软件开发生命周期量身定制的前沿生成式 AI 开发助手,它能够理解亚马逊云科技架构、资源、最佳实践和文档等,并能提供有针对性和可操作的回复和响应。
这篇博客文章演示了如何在 Visual Studio Code 中,利用 Amazon Q Developer 来开发列出指定区域中 Amazon S3 存储桶的代码。文章探讨了在 Amazon Q Developer Agent 的协助下编写新代码,并将新代码与现有的低效“遗留”代码进行详细比较,以及随后通过 Amazon Q Developer 的指导优化该“遗留”代码,从而大幅减少代码执行时间。
如前所述,将旧代码转化为高性能版本并非一蹴而就。在最终实现符合我们预期的优化代码之前,我还是需要与 Amazon Q Developer 进行了三轮详细的沟通互动。如果对互动过程充满好奇,你可以关注我的下一篇博文。这个沟通互动过程其实是非常精彩且富有洞见的,敬请期待。
特别说明:本篇博文的封面图像是由 Amazon Bedrock 上的 Amazon Titan Image Generator G1 模型生成的。
*前述特定亚马逊云科技生成式人工智能相关的服务仅在亚马逊云科技海外区域可用,亚马逊云科技中国仅为帮助您了解行业前沿技术和发展海外业务选择推介该服务。