目录
- 一 、概述
- 1.1 前言
- 1.2 Genimi新版本介绍
- 二、python代码生成
- 2.1 prompt:
- 2.2 Genimi Advanced 回复
- 2.3 Chatgpt4 回复
- 2.4 GPT-4-0125-preview 回复
- 三、文本生成
- 3.1 Prompt
- 3.2 Genimi Advance 回复
- 3.3 Chatgpt4 回复
- 3.3 GPT-4-0125-preview 回复
- 四、分析
- 4.1 Python代码生成
- 4.1.1 运行
- 4.1.2 文本建议
- 4.2 文本生成
- 五、 总结
一 、概述
1.1 前言
Google在2024年2月8日发布了Genimi Ultra(Genimi Advanced)正式商用版本,作为NLP人工智能的爱好者,我也在2月10日试用了Genimi,相比于Chatgpt4,Genimi Advanced可以免费试用2个月,2个月后19.99美金的价格可以选择是否续订。
本篇文章,将使用相同的Prompt,从代码生成和文本生成两个角度横向对比GPT-4-0125-Preview,Chatgpt4、Genimi Advance的输出内容。
1.2 Genimi新版本介绍
首先,我们看下Genimi的发布内容,文章开篇使用了一个极具吸引力的标题《我们双子座时代的下一篇章》,妥妥的UC老粉,看来Google掌握了AI大模型时代的精髓—流量密码。不管好不好用是不是第一,吸引到关注,拉来足够多的流量才是重点。
第一段一个短视频,我没看,直接跳过了,正文前半段一堆吹嘘,大致意思是我们取得了很多进展,遥遥领先,这里就不贴上来了,感兴趣的可以去看原文,链接在这儿: 原文链接
正文感觉比较有价值的信息:
- Bard改名叫Genimi
- Gemini Ultra版本改名叫Genimi Advanced
- 订阅Google One Al Premium就可以用Genimi Advanced
进入Genimi Advanced,显示了订阅价格,亮点是赠了2T的存储空间,相比Chatgpt,这个算是意外之喜了。
需要绑定一个信用卡,才能试用Genimi Advanced,好在赠送了2个月试用,试用结束之后才会开始扣费,可以在试用结束之前退订不扣费。
进入Genimi对话窗口,有2个模型可以选择,Genimi 和Genimi Advanced
二、python代码生成
本文会在Chatgpt4、GPT-4-0125-Preview、Genimi Advaced中使用相同的Prompt,然后将三者的输出贴出来,方便大家横向对比输出内容效果。Prompt中是我以前写的半成品python代码。
2.1 prompt:
你现在的角色是一个python软件开发工程师,你对python进行GUI编程非常了解。请帮我优化以下的python代码
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QComboBox, QLineEdit, QRadioButton, QPlainTextEditimport sysclass MainWindow(QWidget):def __init__(self):super().__init__()# 创建一个垂直布局,用于添加控件self.layout = QVBoxLayout()# 设备端口选择(COM0、COM1等),是一个下拉列表self.combo_box_port = QComboBox()self.combo_box_port.addItem('COM0')self.combo_box_port.addItem('COM1')self.layout.addWidget(self.combo_box_port)# Modbus串口通讯参数设置:波特率—下拉列表、校验位-单选控件、停止位—单选控件、数据位—单选控件、从站号—输入框(输入范围0~255的整数)self.combo_box_baudrate = QComboBox()self.combo_box_baudrate.addItem('9600')self.combo_box_baudrate.addItem('19200')self.layout.addWidget(self.combo_box_baudrate)self.radio_parity = QRadioButton("Parity")self.layout.addWidget(self.radio_parity)self.radio_stopbit = QRadioButton("Stop Bit")self.layout.addWidget(self.radio_stopbit)self.radio_databit = QRadioButton("Data Bit")self.layout.addWidget(self.radio_databit)self.slave_address = QLineEdit("0")self.layout.addWidget(self.slave_address)# 通讯收发数据帧显示控件,一个显示Serial_Error接收到的数据和发送到的数据的控件self.text_frame = QPlainTextEdit()self.layout.addWidget(self.text_frame)# Modbus错误码选择—下拉列表self.combo_box_error_code = QComboBox()self.combo_box_error_code.addItem('Illegal function code')self.combo_box_error_code.addItem('Illegal data address')self.layout.addWidget(self.combo_box_error_code)# 启动按钮—按钮控件self.start_button = QPushButton('Start')self.layout.addWidget(self.start_button)self.setLayout(self.layout)# 使用以下代码可以创建一个窗口并显示出来app = QApplication(sys.argv)window = MainWindow()window.show()app.exec_()
2.2 Genimi Advanced 回复
Python代码优化
以下是一些针对您提供的 Python 代码的优化建议:
1. 布局优化:
- 使用
QHBoxLayout
代替QVBoxLayout
布局串口参数设置部分,使界面更加紧凑。 - 使用
QGridLayout
布局 Modbus 错误码和启动按钮,使其排列更加整齐。
2. 代码结构优化:
- 将 Modbus 串口参数设置提取为单独的类或函数,提高代码的复用性。
- 将错误码列表提取为常量字典,方便维护和更新。
3. 控件使用优化:
- 使用
QSpinBox
代替QLineEdit
输入从站号,方便用户输入。 - 使用
QCheckBox
代替QRadioButton
选择校验位、停止位和数据位,减少控件数量。 - 使用
QTableWidget
显示通讯收发数据帧,更加直观易读。
4. 其他优化:
- 使用
pyqtgraph
等库绘制数据曲线,更加直观地展示数据变化。 - 使用多线程处理 Modbus 通讯,提高程序响应速度。
代码示例:
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout, QPushButton, QComboBox, QSpinBox, QCheckBox, QTableWidget, QTableWidgetItemfrom PyQt5.QtCore import Qtimport sysclass SerialPortSettings(QWidget):def __init__(self):super().__init__()self.layout = QHBoxLayout()self.combo_box_port = QComboBox()self.combo_box_port.addItem('COM0')self.combo_box_port.addItem('COM1')self.combo_box_baudrate = QComboBox()self.combo_box_baudrate.addItem('9600')self.combo_box_baudrate.addItem('19200')self.check_box_parity = QCheckBox("Parity")self.check_box_stopbit = QCheckBox("Stop Bit")self.check_box_databit = QCheckBox("Data Bit")self.spin_box_slave_address = QSpinBox()self.spin_box_slave_address.setRange(0, 255)self.layout.addWidget(self.combo_box_port)self.layout.addWidget(self.combo_box_baudrate)self.layout.addWidget(self.check_box_parity)self.layout.addWidget(self.check_box_stopbit)self.layout.addWidget(self.check_box_databit)self.layout.addWidget(self.spin_box_slave_address)self.setLayout(self.layout)class MainWindow(QWidget):def __init__(self):super().__init__()self.layout = QVBoxLayout()self.serial_port_settings = SerialPortSettings()self.text_frame = QTableWidget()self.text_frame.setColumnCount(2)self.text_frame.setHorizontalHeaderLabels(["接收", "发送"])self.combo_box_error_code = QComboBox()self.combo_box_error_code.addItem('Illegal function code')self.combo_box_error_code.addItem('Illegal data address')self.start_button = QPushButton('Start')self.layout.addWidget(self.serial_port_settings)self.layout.addWidget(self.text_frame)self.layout.addWidget(self.combo_box_error_code)self.layout.addWidget(self.start_button)self.setLayout(self.layout)app = QApplication(sys.argv)window = MainWindow()window.show()app.exec_()
优化说明:
- 使用
QHBoxLayout
布局串口参数设置部分,使界面更加紧凑。 - 将 Modbus 串口参数设置提取为单独的类
SerialPortSettings
,提高代码的复用性。 - 使用
QSpinBox
代替QLineEdit
输入从站号,方便用户输入。 - 使用
QCheckBox
代替QRadioButton
选择校验位、停止位和数据位,减少控件数量。 - 使用
QTableWidget
显示通讯收发数据帧,更加直观易读。 - 使用
QGridLayout
布局 Modbus 错误码和启动按钮,使其排列更加整齐。
截图:
2.3 Chatgpt4 回复
你的代码已经是一个非常好的开始,但是我们可以通过一些方法来优化它,让它更加有效和易于维护。以下是一些建议:
- 使用循环来添加相似的控件项:对于需要添加多个相似项的下拉列表(如
QComboBox
),我们可以使用循环来简化代码。 - 分离UI初始化和业务逻辑:将UI组件的初始化放在一个单独的方法中,这样主初始化函数
__init__
会更加清晰。 - 使用更具描述性的变量名:使变量名更具描述性,以便于理解控件的用途。
- 限制QLineEdit的输入:为从站号的输入框(
QLineEdit
)添加输入验证,确保用户只能输入0到255之间的整数。 - 添加注释:在代码中添加更多注释,可以帮助其他开发者(或未来的你)更快地理解代码的意图。
基于这些建议,下面是优化后的代码示例:
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QComboBox, QLineEdit, QRadioButton, QPlainTextEditfrom PyQt5.QtCore import QIntValidatorimport sysclass MainWindow(QWidget):def __init__(self):super().__init__()self.initializeUI()def initializeUI(self):# 初始化UI布局layout = QVBoxLayout()# 设备端口选择self.combo_box_port = self.createComboBox(["COM0", "COM1"])layout.addWidget(self.combo_box_port)# 波特率选择self.combo_box_baudrate = self.createComboBox(['9600', '19200'])layout.addWidget(self.combo_box_baudrate)# 校验位、停止位、数据位单选按钮self.radio_parity = QRadioButton("Parity")self.radio_stopbit = QRadioButton("Stop Bit")self.radio_databit = QRadioButton("Data Bit")layout.addWidget(self.radio_parity)layout.addWidget(self.radio_stopbit)layout.addWidget(self.radio_databit)# 从站地址输入框self.slave_address = QLineEdit("0")self.slave_address.setValidator(QIntValidator(0, 255))# 限制输入范围0~255layout.addWidget(self.slave_address)# 数据帧显示控件self.text_frame = QPlainTextEdit()layout.addWidget(self.text_frame)# Modbus错误码选择self.combo_box_error_code = self.createComboBox(['Illegal function code', 'Illegal data address'])layout.addWidget(self.combo_box_error_code)# 启动按钮self.start_button = QPushButton('Start')layout.addWidget(self.start_button)self.setLayout(layout)def createComboBox(self, items):"""快速创建并填充QComboBox的辅助方法"""combo_box = QComboBox()for item in items:combo_box.addItem(item)return combo_box# 使用以下代码可以创建一个窗口并显示出来app = QApplication(sys.argv)window = MainWindow()window.show()sys.exit(app.exec_())
`
这些改进提高了代码的可读性和可维护性,并使得UI初始化更加模块化。此外,为QLineEdit
添加输入验证是一个重要的改进,它确保用户输入的数据是有效的,从而减少了潜在的错误。
截图
2.4 GPT-4-0125-preview 回复
为了优化你的代码,我会进行以下调整:
- 使用列表来添加下拉菜单的项,减少代码重复。
- 对于具有枚举值选项的控件(如波特率、错误码),定义清晰的列表以改善可读性和维护性。
- 利用循环简化重复的构造步骤,如为下拉框添加多个项。
- 还可以考虑对相似的控件(如单选按钮控件)使用循环或者函数来创建,以进一步简化代码。
以下是优化后的代码部分示例:
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QComboBox, QLineEdit, QRadioButton, QPlainTextEditimport sysclass MainWindow(QWidget):def __init__(self):super().__init__()# 创建一个垂直布局用于添加控件self.layout = QVBoxLayout()# 设备端口选择(COM0、COM1等)self.combo_box_port = QComboBox()port_items = ['COM0', 'COM1']# 可以按需增加更多端口self.combo_box_port.addItems(port_items)self.layout.addWidget(self.combo_box_port)# Modbus串口通讯参数设置:波特率self.combo_box_baudrate = QComboBox()baudrate_items = ['9600', '19200']# 根据需要添加其他波特率self.combo_box_baudrate.addItems(baudrate_items)self.layout.addWidget(self.combo_box_baudrate)# 示例:如何用循环创建单选按钮radio_buttons = ['Parity', 'Stop Bit', 'Data Bit']for btn_label in radio_buttons:radio_button = QRadioButton(btn_label)self.layout.addWidget(radio_button)# 从站地址输入框self.slave_address = QLineEdit("0")self.layout.addWidget(self.slave_address)# 通讯收发数据帧显示控件self.text_frame = QPlainTextEdit()self.layout.addWidget(self.text_frame)# Modbus错误码选择self.combo_box_error_code = QComboBox()error_code_items = ['Illegal function code', 'Illegal data address']self.combo_box_error_code.addItems(error_code_items)self.layout.addWidget(self.combo_box_error_code)# 启动按钮self.start_button = QPushButton('Start')self.layout.addWidget(self.start_button)self.setLayout(self.layout)# 使用以下代码可以创建一个窗口并显示出来app = QApplication(sys.argv)window = MainWindow()window.show()app.exec_()
这种方法简化了为下拉列表和其他重复项添加数据的步骤,并使代码更清晰、易于维护。如果有进一步的需求或者特定的优化方向,请随时告诉我。
截图:
三、文本生成
3.1 Prompt
你现在的角色是一个有十年工作经验的软件测试工程师,你对嵌入式设备的软件测试非常了解。你现在需要测试嵌入式设备的CPU和内存性能(运行在linux系统,黑盒测试),请使用结构化思维模型,提出测试点,每个测试点要详细说明测试步骤和预期结果
3.2 Genimi Advance 回复
嵌入式设备 CPU 和内存性能测试点
测试环境:
- 硬件: 嵌入式设备 (例如: 路由器, 智能家居设备)
- 软件: Linux 操作系统
测试目标:
- 评估嵌入式设备的 CPU 和内存性能
- 识别性能瓶颈
- 验证系统是否满足性能需求
测试方法:
- 黑盒测试
测试点:
1. CPU 性能测试
测试点 1.1: CPU 使用率测试
测试步骤:
- 使用
top
或htop
命令查看 CPU 使用率 - 运行不同负载 (例如: CPU 密集型应用程序) 并观察 CPU 使用率变化
- 使用
预期结果:
- CPU 使用率在正常范围内 (例如: 不超过 80%)
- CPU 使用率不会持续飙高
测试点 1.2: CPU 性能基准测试
测试步骤:
- 使用
sysbench
或lmbench
等工具进行 CPU 性能基准测试 - 将测试结果与其他类似设备进行比较
- 使用
预期结果:
- CPU 性能符合预期
- CPU 性能与同类设备相比具有竞争力
2. 内存性能测试
测试点 2.1: 内存使用率测试
测试步骤:
- 使用
free
命令查看内存使用率 - 运行不同负载 (例如: 内存密集型应用程序) 并观察内存使用率变化
- 使用
预期结果:
- 内存使用率在正常范围内 (例如: 不超过 80%)
- 内存使用率不会持续飙高
测试点 2.2: 内存性能基准测试
测试步骤:
- 使用
sysbench
或lmbench
等工具进行内存性能基准测试 - 将测试结果与其他类似设备进行比较
- 使用
预期结果:
- 内存性能符合预期
- 内存性能与同类设备相比具有竞争力
3. 其他测试点
测试点 3.1: CPU 和内存压力测试
测试步骤:
- 同时运行 CPU 和内存密集型应用程序
- 观察系统性能是否出现明显下降
预期结果:
- 系统性能不会出现明显下降
- 系统能够稳定运行
测试点 3.2: 功耗测试
测试步骤:
- 在不同负载情况下测量设备功耗
- 分析功耗与 CPU 和内存使用率之间的关系
预期结果:
- 功耗与 CPU 和内存使用率成正比
- 功耗在正常范围内
测试报告:
测试报告应包括以下内容:
- 测试环境
- 测试目标
- 测试方法
- 测试结果
- 结论
注意:
- 以上测试点仅供参考,实际测试内容需要根据具体需求进行调整。
- 测试过程中需要注意收集详细的测试数据,以便进行分析和判断。
参考资料:
- Linux CPU Performance Testing:
- Linux Memory Performance Testing:
- Sysbench: https://sysbench.sourceforge.io/
- Lmbench:
截图:
3.3 Chatgpt4 回复
作为一名有十年工作经验的软件测试工程师,对于嵌入式设备的CPU和内存性能测试,我们可以采用黑盒测试方法来进行。以下是基于结构化思维模型提出的测试点,包括详细的测试步骤和预期结果:
1. CPU性能测试
测试点1:CPU计算性能
- 测试步骤:
- 选择或设计用于CPU性能测试的基准测试软件,如Sysbench、Lmbench等。
- 在嵌入式设备上安装并运行基准测试软件。
- 执行计算密集型任务,例如质数计算、浮点运算等。
- 记录CPU的处理速度和完成任务的时间。
- 预期结果:CPU能够在预定的时间内完成计算任务,且处理速度符合设备规格说明书中的性能指标。
测试点2:多任务处理能力
- 测试步骤:
- 同时运行多个计算密集型和I/O密集型任务。
- 监控CPU的利用率、上下文切换次数以及任务响应时间。
- 分析任务并发执行时CPU的表现。
- 预期结果:CPU能够有效地管理多任务,并保持较高的利用率,同时确保任务响应时间合理。
2. 内存性能测试
测试点1:内存读写速度
- 测试步骤:
- 使用内存性能测试工具,如Memtest86+或者是Stream等。
- 在嵌入式设备上执行内存读写操作。
- 记录内存的读写速度。
- 预期结果:内存的读写速度达到设备规格说明书中的标准。
测试点2:内存容量及泄露测试
- 测试步骤:
- 通过运行能够逐渐增加内存使用的应用程序。
- 监控内存使用情况,包括总量和剩余可用量。
- 检查长时间运行后的内存泄露情况。
- 预期结果:内存容量符合规格要求,长时间运行应用程序后不出现明显的内存泄露。
3. 综合性能测试
测试点:系统稳定性和负载能力
- 测试步骤:
- 使用性能测试工具模拟高负载情况,如压力测试工具Stress或Stress-ng。
- 在高负载下运行系统一定时间。
- 监控系统资源的使用情况,包括CPU、内存、I/O等。
- 观察系统是否出现崩溃、重启或性能显著下降的情况。
- 预期结果:系统能够在高负载下稳定运行,资源使用率保持在合理范围内,不出现系统崩溃或重启的情况。
通过上述测试点的详细测试步骤和预期结果,我们能够全面评估嵌入式设备CPU和内存的性能,确保设备能够满足实际应用中的需求。这些测试不仅关注单一性能指标,而且综合评估设备在实际运行环境中的表现。
截图:
3.3 GPT-4-0125-preview 回复
对于进行嵌入式设备的CPU和内存性能测试,我们可以采用以下结构化思维模型来制定测试计划:
- 测试目标细分:分别针对CPU性能和内存性能制定详细的测试点。
- 定义测试方法:确定采用的压力测试、性能测试工具或手段。
- 测试环境设置:确保测试环境与实际运行环境相仿。
- 测试执行:按照预定步骤执行测试,并记录结果。
- 结果验证:根据预期结果验证测试结果是否符合性能标准。
- 问题报告与分析:对测试中发现的问题进行记录和分析。
1. CPU性能测试点
测试点1:CPU压力测试
测试步骤:
- 使用
stress
或sysbench
工具在Linux系统上生成CPU负载。 - 使用一系列的CPU密集型任务(如大量的计算任务)。
- 观察并记录CPU使用率、系统响应时间等关键指标。
- 可以分别设置不同的并发线程数量,进行多次测试。
- 使用
预期结果:
- CPU使用率应接近但不应长时间保持在100%,避免系统过载。
- 系统响应时间应在合理范围内,无明显延迟。
- 随着并发线程数的增加,系统处理能力应成比例增加,直到达到性能瓶颈。
测试点2:CPU时钟频率及核心数的验证
测试步骤:
- 使用
lscpu
查看CPU的时钟频率与核心数。 - 根据设备规格书核对CPU的时钟频率与核心数。
- 运行并行处理任务,通过
top
或htop
观察各核心的负载。
- 使用
预期结果:
lscpu
输出的CPU时钟频率与核心数与规格书相符。- 各核心在并行任务下均匀负载,无明显的不平衡。
2. 内存性能测试点
测试点1:内存使用率和泄漏测试
测试步骤:
- 使用
valgrind
工具检测内存泄漏。 - 在设备上运行能够持续占用内存资源的任务。
- 使用
free
或top
命令定时监控内存使用情况。
- 使用
预期结果:
- 随着时间推移,内存使用率上升后应稳定,无明显的持续性增长。
valgrind
应不报告任何内存泄漏。
测试点2:内存读写速率测试
测试步骤:
- 使用
dd
命令测量内存到磁盘的写入速率。 - 使用
hdparm
测试内存读取速率。 - 重复多次测试并记录结果。
- 使用
预期结果:
- 内存读写速率应与设备规格书中声明的值相近,且稳定。
- 不同次数的测试结果之间波动小。
以上测试点是在进行黑盒测试时,基于性能角度对嵌入式Linux设备CPU和内存进行检测的基础架构。在真实场景中,可能还需要根据设备的具体应用场景进行一些特定的性能测试。
四、分析
4.1 Python代码生成
4.1.1 运行
三个平台生成的代码,只有Chatgpt4没有运行成功报错了,Genimi Advanced 和 GPT-4-0125-Preview都成功运行,Genimi Advanced 还对生成的UI界面控件布局进行了调整,这一轮Genimi Advaced小胜
Prompt代码运行
Genimi代码运行
运行成功,软件UI界面控制布局进行了调整
Chatgpt
运行失败
GPT-4-0125-preview
运行成功,软件UI界面未变化
4.1.2 文本建议
Python代码生成,横向对比三个回复的文字内容建议,Genimi Adavanced建议增加类,不同类存放不同的功能,同时对控件提出了优化建议。ChatGPT4 建议变量命名描述,也建议了增加类存放不同功能,建议内容感觉平平无奇,垫底。GPT-4-0125-Preview在ChatGPT4基础上,提出了使用枚举来存放异常信息和存放数据。总体而言,Genimi Advanced优化会更激进一些,它会对用户代码中的控件进行更加大胆的改变,比如直接替换某个控件类型,UI方向是集中在控件和布局;ChatGPT4 和 GPT-4-0125-Preview则优化方向相对保守,会保留用户的控件和布局,将优化方向放在代码的变量命名、数据存放、代码结构上来。很难说Genimi Advanced胜出吧,在优化建议上,算是打了一个平手吧。
4.2 文本生成
关于文本生成的结果,让我有一点意外,因为Genimi Advanced和Chatgpt4 生成的信息同质化严重,如果做AB测试,我甚至怀疑这两个才是一家的。GPT-4-0125-Preview则不愧是OPEN AI目前最强大的模型,它首先进行了结构化模型总结,标准的结构化句式。从生成质量上来讲,我心中的1-3名为:GPT-4-0125-Preview、Genimi Advanced、Chatgpt4
五、 总结
从上述的输出结果对比及我的个人分析来看,Genimi Advanced的升级相对前一个产品Bard还是进步明显的,值得大家结合自己的业务场景上手体验一下。