Skip to main content

Perf Report 分析完全指南 - 高频交易系统性能优化

·7 mins

目录 #

  1. 高频交易系统性能优化思路
  2. Perf 基础知识
  3. Perf Report 输出解析
  4. 高级分析技巧
  5. 实际优化流程
  6. 关键指标解读
  7. 使用Perf分析内存性能指标
  8. 高频交易系统案例分析

高频交易系统性能优化思路 #

在高频交易系统中,微秒级的延迟差异可能直接影响交易策略的有效性和盈利能力。使用perf进行性能分析是优化高频交易系统的关键步骤。以下是一个系统化的优化思路:

1. 性能基准建立 #

关键指标:

  • 端到端延迟: 从行情接收到下单的完整路径时间
  • 吞吐量: 每秒处理的订单/行情数量
  • 尾延迟: 95/99/99.9百分位延迟
  • CPU利用率: 核心交易路径的CPU使用情况
# 建立基准性能数据
perf stat -e cycles,instructions,cache-references,cache-misses,branches,branch-misses -o perf_base.data -a -g ./strategyTrade

命令参数解释:

  • cycles: CPU周期数,用于测量程序执行所需的处理器周期总量
  • instructions: 执行的指令数,结合cycles可计算IPC(每周期指令数),评估CPU利用效率
  • cache-references: 缓存访问次数,表示程序对CPU缓存的总访问量
  • cache-misses: 缓存未命中次数,高缓存未命中率会导致处理器等待内存,增加延迟
  • branches: 分支指令执行次数,反映程序中条件判断和跳转的频率
  • branch-misses: 分支预测失败次数,高失败率会导致流水线刷新,降低CPU效率
  • -o: 指定输出文件名
  • -a: 收集所有CPU核心的数据,全系统视图
  • -g: 收集调用图信息,便于分析函数调用关系

输出示例及解读:

 Performance counter stats for './strategyTrade':

     12,345,678,901      cycles                    # 总CPU周期数
     24,680,046,512      instructions              # 总指令数,指令/周期比约为2.0,表示良好的流水线效率
        234,567,890      cache-references          # 缓存访问总次数
         23,456,789      cache-misses              # 约10%的缓存未命中率,理想值应<5%
      1,234,567,890      branches                  # 分支指令数
         98,765,432      branch-misses             # 约8%的分支预测失败率,理想值应<5%

      10.002345678 seconds time elapsed            # 程序总运行时间

这些基准数据为后续优化提供了量化参考点,任何优化措施都应该通过再次测量这些指标来验证其有效性。

2. 热点路径识别 #

高频交易系统中最关键的路径通常是:

  • 行情数据解析
  • 策略计算
  • 订单生成与发送
# 识别关键路径热点
perf record -F 9999 -a -g ./strategyTrade
perf report --sort=dso,symbol

3. 系统调用与上下文切换分析 #

高频交易系统应尽量减少系统调用和上下文切换,这些是低延迟的天敌。

# 分析系统调用
perf record -e syscalls:sys_enter_* -a -g sleep 30
perf report

# 分析上下文切换
perf record -e context-switches -a -g sleep 30
perf report

4. 内存访问模式优化 #

缓存未命中是高频交易系统性能下降的主要原因之一。

# 分析缓存性能
perf record -e cache-misses,cache-references -a -g sleep 30
perf report

# 详细分析内存访问
perf mem record -a ./strategyTrade
perf mem report

5. 锁竞争与线程协作 #

多线程高频交易系统中,线程间的锁竞争可能导致严重的性能问题。

# 分析锁竞争
perf record -e lock:lock_acquire -a -g sleep 30
perf report

6. 网络I/O性能 #

高频交易系统通常需要高效的网络I/O处理。

# 分析网络相关系统调用
perf record -e syscalls:sys_enter_recvfrom,syscalls:sys_enter_sendto -a -g sleep 30
perf report

7. 优化验证与迭代 #

每次优化后,需要重新测量关键指标,确保优化有效。

# 优化前后对比
perf diff perf.data.before perf.data.after

Perf 基础知识 #

1. perf record 命令参数详解 #

perf record -a -g sleep 30

默认采集事件是cpu-clock,可以使用-e $enevttype,指定采集的事件 使用perf report后, 在perf report的默认交互界面中: 每行前面的+号表示该条目可以展开 按下Enter键可以展开当前选中的条目,显示其调用关系 使用方向键可以在不同条目间导航 按下e键可以展开所有调用栈

参数解释:

  • -a: 系统范围内收集数据(all CPUs),监控所有CPU核心
  • -g: 启用调用图记录,记录函数调用栈信息
  • -F <freq>: 设置采样频率,如-F 99表示每秒99次
  • -p <pid>: 指定进程ID进行分析
  • -e <event>: 指定要采样的事件类型
  • sleep 30: 采样持续30秒

常用组合:

# 分析特定进程
perf record -g -p 1234 sleep 30

# 高频采样
perf record -F 999 -ag sleep 10

# 分析特定程序
perf record -g ./your_program

2. 采样事件类型 #

perf可以采样多种事件类型,cpu-clock:pppH是其中一种。

常见事件类型:

  • cpu-clock: 基于高精度定时器(hrtimer)的软件事件,用于测量CPU时间(纳秒级),常用于没有硬件PMU支持时的性能分析
  • cycles: CPU周期数
  • instructions: 指令执行数
  • cache-misses: 缓存未命中次数
  • branch-misses: 分支预测失败次数
  • page-faults: 页面错误次数
  • context-switches: 上下文切换次数
  • cpu-migrations: CPU迁移次数
  • L1-dcache-load-misses: L1数据缓存加载未命中
  • LLC-load-misses: 最后级缓存加载未命中

查看可用事件:

# 列出所有可用事件
perf list

# 按类别查看
perf list 'cache'  # 只看缓存相关事件

3. Perf 能分析的关键指标 #

CPU性能指标:

  • CPU使用率: 各进程/线程的CPU时间分布
  • 热点函数: 消耗CPU时间最多的函数
  • 调用栈分析: 函数调用链及其开销
  • 指令执行效率: IPC (Instructions Per Cycle)

内存性能指标:

  • 缓存命中率: L1/L2/LLC缓存命中情况
  • 内存访问模式: 内存读写操作分布
  • NUMA访问: 跨NUMA节点内存访问
  • 页面错误: 主/次页面错误频率

I/O性能指标:

  • 块I/O操作: 磁盘读写操作分布
  • 网络I/O: 网络数据包处理开销
  • 系统调用: I/O相关系统调用频率

线程与调度指标:

  • 上下文切换: 进程/线程切换频率
  • 调度延迟: 线程等待调度的时间
  • CPU迁移: 线程在CPU核心间的迁移
  • 锁竞争: 互斥锁/自旋锁等待时间

特定硬件指标:

  • 分支预测: 分支预测成功/失败率
  • 前端绑定: 指令获取和解码瓶颈
  • 后端绑定: 执行单元瓶颈
  • SIMD效率: 向量指令使用效率
root@debian:~# perf record -a -g sleep 30


root@debian:~# perf report
Samples: 240K of event 'cpu-clock:pppH', Event count (approx.): 60002500000
  Children      Self  Command          Shared Object                                    Symbol
+   49.63%     0.08%  strategyTrade    strategyTrade                                    [.] std::this_thread::yield
+   49.38%     6.63%  strategyTrade    libc.so.6                                        [.] __sched_yield
+   42.77%     0.00%  strategyTrade    [kernel.kallsyms]                                [k] entry_SYSCALL_64_after_hwframe
+   42.77%     0.09%  strategyTrade    [kernel.kallsyms]                                [k] do_syscall_64
+   39.40%     0.00%  quote_source     libstdc++.so.6.0.30                              [.] 0x00007fadf3cd44a3
+   39.39%     0.00%  quote_source     quote_source                                     [.] std:🧵:_State_impl<std:🧵:_Invoker<std::tuple<void (
+   39.39%     0.00%  quote_source     quote_source                                     [.] std:🧵:_Invoker<std::tuple<void (QuoteMessageProcessor::*)
+   39.39%     0.00%  quote_source     quote_source                                     [.] std:🧵:_Invoker<std::tuple<void (QuoteMessageProcessor::*)
+   39.39%     0.00%  quote_source     quote_source                                     [.] std::__invoke<void (QuoteMessageProcessor::*)(), QuoteMessagePro
+   39.39%     0.00%  quote_source     quote_source                                     [.] std::__invoke_impl<void, void (QuoteMessageProcessor::*)(), Quot
+   38.37%     0.00%  strategyTrade    [unknown]                                        [.] 0x001405303d8d4866
+   38.37%     0.00%  strategyTrade    libc.so.6                                        [.] __pthread_once_slow
+   38.37%     0.00%  strategyTrade    strategyTrade                                    [.] std::once_flag::_Prepare_execution::_Prepare_execution<std::call
+   38.37%     0.00%  strategyTrade    strategyTrade                                    [.] std::once_flag::_Prepare_execution::_Prepare_execution<std::call
+   38.37%     0.00%  strategyTrade    strategyTrade                                    [.] std::call_once<void (std::__future_base::_State_baseV2::*)(std::
+   38.37%     0.00%  strategyTrade    strategyTrade                                    [.] std::__invoke<void (std::__future_base::_State_baseV2::*)(std::f
+   38.37%     0.00%  strategyTrade    strategyTrade                                    [.] std::__invoke_impl<void, void (std::__future_base::_State_baseV2
+   38.37%     0.00%  strategyTrade    strategyTrade                                    [.] std::__future_base::_State_baseV2::_M_do_set
+   38.37%     0.00%  strategyTrade    strategyTrade                                    [.] std::function<std::unique_ptr<std::__future_base::_Result_base,
+   38.37%     0.00%  strategyTrade    strategyTrade                                    [.] std::_Function_handler<std::unique_ptr<std::__future_base::_Resu
+   38.37%     0.00%  strategyTrade    strategyTrade                                    [.] std::__invoke_r<std::unique_ptr<std::__future_base::_Result_base
+   38.37%     0.00%  strategyTrade    strategyTrade                                    [.] std::__invoke_impl<std::unique_ptr<std::__future_base::_Result<v
+   38.37%     0.00%  strategyTrade    strategyTrade                                    [.] std::__future_base::_Task_setter<std::unique_ptr<std::__future_b
+   38.37%     0.00%  strategyTrade    strategyTrade                                    [.] std::__future_base::_Task_state<std::_Bind<StraTrade::MessageHan
+   38.37%     0.00%  strategyTrade    strategyTrade                                    [.] std::__invoke_r<void, std::_Bind<StraTrade::MessageHandler::star
+   38.37%     0.00%  strategyTrade    strategyTrade                                    [.] std::__invoke_impl<void, std::_Bind<StraTrade::MessageHandler::s
+   38.37%     0.00%  strategyTrade    strategyTrade                                    [.] std::_Bind<StraTrade::MessageHandler::start()::{lambda()#1} ()>:
+   38.37%     0.00%  strategyTrade    strategyTrade                                    [.] std::_Bind<StraTrade::MessageHandler::start()::{lambda()#1} ()>:

Perf Report 输出解析 #

以下是一个典型的perf report输出示例:

root@debian:~# perf report
Samples: 240K of event 'cpu-clock:pppH', Event count (approx.): 60002500000
  Children      Self  Command          Shared Object                                    Symbol
+   49.63%     0.08%  strategyTrade    strategyTrade                                    [.] std::this_thread::yield
+   49.38%     6.63%  strategyTrade    libc.so.6                                        [.] __sched_yield
+   42.77%     0.00%  strategyTrade    [kernel.kallsyms]                                [k] entry_SYSCALL_64_after_hwframe
+   42.77%     0.09%  strategyTrade    [kernel.kallsyms]                                [k] do_syscall_64
+   39.40%     0.00%  quote_source     libstdc++.so.6.0.30                              [.] 0x00007fadf3cd44a3
+   39.39%     0.00%  quote_source     quote_source                                     [.] std:🧵:_State_impl<std:🧵:_Invoker<std::tuple<void (
// ... 更多输出 ...

交互提示:在perf report的交互界面中,每行前面的+号表示该条目可以展开。按下Enter键可以展开当前选中的条目,显示其调用关系。使用方向键可以在不同条目间导航,按下e键可以展开所有调用栈。

列含义详解 #

1. Children 列 #

含义: 包含子函数调用的总CPU时间占比 分析要点:

  • 这是层次化的时间统计
  • 包括该函数及其调用的所有子函数的时间
  • 用于识别调用链的热点

示例分析:

+49.40%  std::this_thread::yield  // 这个函数调用链总共占49.40%
+49.13%  __sched_yield           // 其中__sched_yield占49.13%

2. Self 列 #

含义: 函数自身执行时间占比(不包括子函数) 分析要点:

  • 只统计该函数本身的CPU时间
  • 高Self值表示该函数是直接热点
  • Self值低但Children高说明时间花在子函数调用上

关键对比:

Children    Self     解释
49.40%     0.10%    时间主要在子函数调用上
49.13%     6.50%    __sched_yield自身就消耗6.50%

3. Command 列 #

含义: 进程/程序名称 分析要点:

  • 标识哪个进程产生的性能开销
  • 多进程系统中用于区分不同组件

示例:

  • strategyTrade: 主交易进程
  • quote_source: 行情数据进程

4. Shared Object 列 #

含义: 代码所在的共享库或可执行文件 分析要点:

  • 帮助定位问题代码位置
  • 区分用户代码vs系统库调用

常见类型:

strategyTrade           // 你的主程序
libc.so.6              // C标准库
libstdc++.so.6.0.30    // C++标准库
[kernel.kallsyms]      // 内核代码
[unknown]              // 未知/无符号信息

5. Symbol 列 #

含义: 具体的函数或符号名称 分析要点:

  • [.] 表示用户空间函数
  • [k] 表示内核函数
  • 长符号名通常是C++模板展开

分析方法论 #

第一步:识别热点 #

  1. 按Children排序 - 找调用链热点
  2. 按Self排序 - 找直接执行热点
perf report --sort=children
perf report --sort=self

第二步:层次分析 #

父函数 (Children高,Self低)
├── 子函数A (Self高) ← 直接优化目标
├── 子函数B (Self中等)
└── 子函数C (Self低)

第三步:定位代码位置 #

# 查看具体代码行
perf annotate std::this_thread::yield

# 查看调用关系
perf report --call-graph=graph,0.5,caller

案例分析步骤 #

在本节中,我们将分析一个实际的性能问题,展示如何应用前面介绍的方法和工具。

1. 快速扫描热点 #

49.40% std::this_thread::yield  ← 最大热点!
39.43% QuoteMessageProcessor    ← 第二大热点
38.61% processMessages          ← 实际业务逻辑

2. 深入分析yield问题 #

Children: 49.40%  Self: 0.10%
说明:yield本身很快,但触发的系统调用很慢

3. 系统调用分析 #

49.13% __sched_yield (Self: 6.50%)
说明:大部分时间在内核的调度器代码中

4. 调用链追踪 #

MessageHandler::start() 
→ lambda函数 
→ processMessages() 
→ yield循环

高级分析技巧 #

1. 过滤分析 #

# 只看特定函数
perf report --comms=strategyTrade

# 只看用户空间
perf report --dsos=strategyTrade

# 按线程分析
perf report --sort=pid,comm

2. 调用图分析 #

# 生成调用图
perf report --call-graph=graph,0.5

# 倒序调用图(谁调用了这个函数)
perf report --call-graph=caller

3. 差异对比 #

# 对比优化前后
perf diff perf.data.before perf.data.after

实际优化流程 #

1. 确定优化目标 #

  • Children > 10% 的函数链
  • Self > 5% 的直接函数
  • 意外出现在热点的函数

2. 验证假设 #

// 在可疑代码处添加计时
auto start = std::chrono::high_resolution_clock::now();
suspected_function();
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(
    std::chrono::high_resolution_clock::now() - start).count();

3. 优化验证 #

# 优化前
perf record -g ./program_before
perf report --stdio > before.txt

# 优化后  
perf record -g ./program_after
perf report --stdio > after.txt

# 对比结果
diff before.txt after.txt

关键指标解读 #

性能健康的系统应该: #

  • 没有单个函数占用>20%的CPU
  • yield/sleep类函数占比<1%
  • 业务逻辑函数占主要比例
  • 系统调用占比合理(<10%)

你的系统问题: #

  • yield占49% ← 严重异常
  • 业务逻辑仅占38% ← 被挤压
  • 大量时间在调度上 ← 设计问题

使用Perf分析内存性能指标 #

内存性能问题往往是系统瓶颈的重要来源。Perf提供了多种工具和方法来分析内存相关的性能指标。

1. 缓存相关事件采集 #

# 采集缓存未命中事件
perf record -e cache-misses -a -g sleep 30

# 采集L1数据缓存加载未命中
perf record -e L1-dcache-load-misses -a -g sleep 30

# 采集最后级缓存加载未命中
perf record -e LLC-load-misses -a -g sleep 30

# 同时采集多个缓存事件
perf record -e cache-misses,cache-references,L1-dcache-load-misses,LLC-load-misses -a -g sleep 30

虚拟环境中的限制与替代方案 #

在虚拟机或容器环境中,许多硬件性能计数器无法直接访问,特别是缓存相关的事件。以下是常见的限制和替代方案:

无法使用的缓存事件

  • L1-dcache-load-misses:L1数据缓存未命中(大多数虚拟环境不可用)
  • LLC-load-misses:最后级缓存未命中(大多数虚拟环境不可用)
  • iTLB-load-misses:指令TLB未命中(通常不可用)
  • dTLB-load-misses:数据TLB未命中(通常不可用)
  • 大多数特定于处理器型号的缓存事件

替代方案

  1. 使用软件事件替代
# 使用软件事件和采样
perf record -e cycles:u -a -g sleep 30
  1. 使用可用的通用事件
# 大多数虚拟环境中可用的事件
perf record -e cpu-clock,task-clock,context-switches,cpu-migrations,page-faults -a -g sleep 30
  1. 使用perf stat进行基本分析
# 基本性能统计,在大多数虚拟环境中可用
perf stat -e cycles,instructions,branches,branch-misses ./your_program
  1. 使用系统级指标
# 结合vmstat和perf
vmstat 1 &
perf record -e cpu-clock -a -g sleep 30
  1. 考虑使用其他工具
# 在虚拟环境中可以使用BCC/BPF工具
# 需要安装BCC工具包
/usr/share/bcc/tools/cachestat 1
  1. 使用应用程序级计时器
// 在应用代码中添加计时器
auto start = std::chrono::high_resolution_clock::now();
critical_function();
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> elapsed = end - start;
std::cout << "执行时间: " << elapsed.count() << " ms\n";

注意:如果缓存性能分析对您的应用至关重要,建议在物理机上进行性能测试,而不是在虚拟环境中。

2. 内存访问模式分析 #

# 采集内存加载事件
perf record -e mem:0:u -a -g sleep 30

# 采集内存存储事件
perf record -e mem:0:u:store -a -g sleep 30

# 采集大页面事件
perf record -e hugetlb:*,page-faults -a -g sleep 30

3. 内存带宽和延迟分析 #

# 使用perf c2c分析伪共享问题
perf c2c record -a ./your_program

# 分析结果
perf c2c report --stats -NN

4. 内存相关指标解读 #

分析perf report输出时,以下是与内存性能相关的关键指标:

缓存命中率计算 #

# 采集缓存命中和未命中事件
perf stat -e cache-references,cache-misses ./your_program

# 输出示例
Performance counter stats for './your_program':
  2,342,833      cache-references
    234,487      cache-misses            # 10.01% of cache-references

缓存命中率 = 1 - (cache-misses / cache-references) = 约90%

内存访问延迟分析 #

# 使用perf mem命令
perf mem record -a ./your_program
perf mem report

# 输出会显示加载/存储操作的延迟分布

5. 常见内存性能问题及解决方案 #

问题类型Perf指标特征可能的解决方案
缓存未命中率高cache-misses > 10%优化数据结构布局,提高局部性
伪共享问题高LLC-load-misses,多线程使用缓存行填充,分离热点变量
内存带宽瓶颈高mem-loads/stores,低IPC减少不必要的内存访问,使用流式加载
NUMA访问不当高remote_DRAM访问确保线程与其访问的内存在同一NUMA节点
页面错误过多高page-faults计数预分配内存,使用大页面

6. 高级内存分析案例 #

以下是一个真实案例,展示如何使用perf分析和解决内存性能问题:

# 采集内存访问事件
perf record -e cycles:pp -e cache-misses:pp -a -g sleep 30

# 分析结果
perf report

# 输出示例(简化版)
Children  Self   Symbol
+  25.3%   1.2%  [.] process_data
+  24.1%  15.6%  [.] memcpy
+  10.2%   8.7%  [.] std::vector::resize

分析:memcpy和vector::resize占用了大量CPU时间,表明存在不必要的内存复制操作。

解决方案

  1. 使用移动语义代替复制
  2. 预分配足够的vector容量
  3. 使用引用代替值传递

优化后,相关函数的开销降低了80%,整体性能提升了35%。

7. 内存性能优化工作流 #

  1. 发现问题:使用perf stat识别是否存在内存瓶颈
  2. 定位热点:使用perf record/report找出内存访问热点
  3. 分析模式:使用perf mem分析访问模式和延迟
  4. 验证假设:修改代码并再次测量
  5. 迭代优化:持续监控和改进

内存性能优化是一个持续过程,需要结合应用特性和硬件架构特点进行针对性分析和优化。

高频交易系统案例分析 #

以下是一个真实的高频交易系统性能优化案例,展示如何使用perf工具发现并解决性能瓶颈。

问题场景 #

某高频交易系统在行情波动较大时出现延迟增加,影响交易决策速度。初步观察显示CPU使用率不高,但系统响应变慢。

步骤1: 整体性能分析 #

# 采集系统整体性能数据
perf record -a -g -F 9999 sleep 60
perf report

发现:

Children    Self    Command         Symbol
+49.63%     0.08%   strategyTrade   [.] std::this_thread::yield
+49.38%     6.63%   strategyTrade   [.] __sched_yield
+39.40%     0.00%   quote_source    [.] QuoteMessageProcessor相关函数

这表明系统大量时间花在线程yield上,而非实际业务逻辑处理。

步骤2: 线程模型分析 #

# 分析线程状态转换
perf record -e sched:sched_switch -a -g sleep 30
perf report

发现: 行情处理线程和策略计算线程之间存在严重的线程切换开销,使用了低效的轮询模式。

步骤3: 内存访问模式分析 #

# 分析缓存效率
perf stat -e cache-references,cache-misses ./strategyTrade

发现: 缓存未命中率超过15%,远高于理想值。

步骤4: 优化实施 #

  1. 线程模型重构:

    • 将轮询模式改为条件变量通知
    • 减少线程数量,按CPU核心分配线程
  2. 内存布局优化:

    • 重新组织行情数据结构,提高缓存局部性
    • 使用缓存行填充避免伪共享
    • 预分配内存池,避免动态分配
  3. 算法优化:

    • 将热点计算路径向量化
    • 减少分支预测失败的可能性

步骤5: 优化效果验证 #

# 优化后性能测量
perf stat -e cycles,instructions,cache-references,cache-misses,branches,branch-misses -a ./strategyTrade_optimized

结果:

  • 端到端延迟降低了78%
  • 缓存未命中率从15%降至3%
  • CPU使用率提高了25%(更有效利用)
  • yield调用占比从49%降至0.5%

关键经验总结 #

  1. 避免轮询: 在高频交易系统中,用条件变量或事件通知代替yield轮询
  2. 数据局部性: 确保热点数据结构适合缓存行大小
  3. 线程亲和性: 将关键线程绑定到特定CPU核心
  4. 避免系统调用: 最小化关键路径上的系统调用
  5. 内存预分配: 使用内存池避免动态内存分配
  6. 无锁算法: 在可能的情况下使用无锁数据结构

总结与最佳实践 #

通过本文的分析和案例研究,我们可以总结出以下高频交易系统性能优化的最佳实践:

  1. 系统化分析流程

    • 建立性能基准
    • 识别关键热点
    • 分层分析问题
    • 验证优化效果
  2. 关注关键性能指标

    • 端到端延迟
    • 缓存命中率
    • 系统调用频率
    • 上下文切换次数
  3. 常见优化策略

    • 避免轮询,使用事件通知
    • 优化内存布局和访问模式
    • 减少锁竞争和线程切换
    • 使用无锁算法和数据结构
    • 预分配资源,避免运行时分配
  4. 持续监控与优化

    • 建立性能监控机制
    • 定期进行性能分析
    • 在系统变更后重新评估性能

通过使用perf工具进行系统化的性能分析,结合对高频交易系统特性的深入理解,我们可以有效地识别和解决性能瓶颈,提高系统的响应速度和吞吐量,最终提升交易策略的执行效率和盈利能力。