如何准确测量 Android 应用中 Activity 和 Fragment 的启动时间

如何准确测量 Android 应用中 Activity 和 Fragment 的启动时间

在 Android 应用开发中,了解每个 Activity 和 Fragment 的启动时间对于性能优化至关重要。本文将介绍几种方法来准确测量 Activity 和 Fragment 的启动时间,并提供实际操作步骤,以帮助提升应用的响应速度和用户体验。


1. 使用 adb shell am start -W 命令

adb shell am start -W 命令是一种简单且直接的方法,用于测量 Activity 的启动时间。该命令启动指定的 Activity 并输出相关的时间数据。以下是如何使用该命令,以及如何解决常见错误。

1.1 命令

adb shell am start -W -n <your.package.name>/<your.package.name.yourActivity>

1.2 输出解释

  • ThisTime: 当前 Activity 的启动时间。
  • TotalTime: 从应用启动到当前 Activity 的总时间。
  • WaitTime: 系统等待时间。

1.3 启动 Activity 并传递参数

使用 -e 选项传递参数

要传递键值对参数,可以使用 -e 选项。-e 选项用于将一个字符串键值对传递给目标 Activity。如果有多个键值对需要传递,可以使用多个 -e 选项。

命令格式
adb shell am start -n <your.package.name>/<your.package.name.YourActivity> -e <key1> <value1> -e <key2> <value2> ...
  • -n <your.package.name>/<your.package.name.YourActivity>:指定要启动的 Activity
  • -e <key> <value>:指定要传递的参数及其对应的值。key 是参数的名称,value 是参数的值。
示例

应用程序包名为 com.example.app,要启动的 Activitycom.example.app.ui.MainActivity,并且需要传递两个参数:user_idsession_token。可以使用以下命令:

adb shell am start -n com.example.app/com.example.app.ui.MainActivity -e user_id 12345 -e session_token abcdef123456
传递多种数据类型

除了使用 -e 选项传递字符串参数,还可以使用以下选项传递其他数据类型的参数:

  • -e:传递字符串键值对。
  • -en:传递整数键值对。
  • -ef:传递浮点数键值对。
  • -el:传递长整型键值对。
  • -eb:传递布尔键值对。
  • -eia:传递整数数组键值对。
  • -efa:传递浮点数数组键值对。
示例

如果需要传递一个整数和一个布尔值参数,可以使用以下命令:

adb shell am start -n com.example.app/com.example.app.ui.MainActivity -en max_retries 5 -eb is_active true

在这个例子中,max_retries 是一个整数参数,is_active 是一个布尔参数。

解析传递的参数

在的 Activity 中,可以通过 Intent 对象来获取传递的参数。例如:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent intent = getIntent();
        String userId = intent.getStringExtra("user_id");
        String sessionToken = intent.getStringExtra("session_token");

        // 使用获取的参数
    }
}

对于其他数据类型的参数,可以使用对应的 Intent 方法进行获取,例如 getIntExtragetBooleanExtra 等。


通过使用 -e 及相关选项,可以方便地将参数传递给 Activity,在测试和调试过程中模拟各种条件。这使得验证应用程序的不同功能变得更加高效和灵活。

1.4 常见错误及解决方案

1.4.1 java.lang.SecurityException: Permission Denial

错误信息:

java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.example.myapp/.MainActivity mCallingUid=2000 } from null (pid=29129, uid=2000) not exported from uid 10600

原因: 当尝试启动的 Activity 没有配置为导出的或没有适当的权限时,会出现此错误。

解决方案:

  1. 修改 AndroidManifest.xml: 确保目标 Activity 已配置为 exported="true",这样才能允许外部调用。

    <activity
        android:name=".MainActivity"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    
  2. 检查权限: 确保应用具有适当的权限,或尝试使用 adb 命令以 root 权限运行。

1.4.2 java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.example.myapp/.MainActivity } from null (pid=29219, uid=2000) not exported from uid 10600

错误信息:

java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.example.myapp/.MainActivity mCallingUid=2000 } from null (pid=29219, uid=2000) not exported from uid 10600

原因: 该错误通常表示目标 Activity 没有正确配置为导出或启动。即使 Activity 是导出的,它可能没有正确设置 intent-filterlaunchMode

解决方案:

  1. 配置 intent-filter: 确保 Activity 正确配置了 intent-filter,如果需要,它应包括 MAINLAUNCHER 动作和类别。

    <activity
        android:name=".MainActivity"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    
  2. 检查启动模式: 如果 Activity 是内部活动或不需要被外部启动,考虑使用其他方法测试,或者设置 android:exported="true" 确保外部调用。

1.4.3 ActivityNotFoundException

错误信息:

android.content.ActivityNotFoundException: Unable to find explicit activity class {com.example.myapp/.MainActivity}; have you declared this activity in your AndroidManifest.xml?

原因: 该错误表示系统无法找到指定的 Activity。这可能是因为在 AndroidManifest.xml 中没有正确声明该 Activity,或包名和类名错误。

解决方案:

  1. 检查 AndroidManifest.xml: 确保目标 Activity 已在 AndroidManifest.xml 中正确声明。

    <activity
        android:name=".MainActivity"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    
  2. 核对包名和类名: 确保 adb 命令中的包名和类名与实际声明的一致。


2. 手动记录启动时间

为了获得更准确的数据,可以在代码中手动记录每个 Activity 的启动时间。这种方法能够提供更符合实际使用场景的数据。

2.1 代码

在每个 Activity 的 onCreate 方法中记录启动时间:

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        long startTime = System.currentTimeMillis();
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        long elapsedTime = System.currentTimeMillis() - startTime;
        Log.d(TAG, "Activity startup time: " + elapsedTime + " ms");
    }
}

2.2 捕获日志

使用 adb logcat 捕获启动时间日志:

adb logcat -s MainActivity

3. 使用 Application.ActivityLifecycleCallbacks 接口记录activity启动时长

为了自动记录每个 Activity 的启动时间,避免在每个 Activity 中重复编写代码,可以使用 Application.ActivityLifecycleCallbacks 接口。

3.1使用注解标记中文名

首先,我们创建一个自定义注解来标记 Activity 的中文名。

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface ChineseName {
    String value();
}

然后,在每个 Activity 类上使用这个注解。

import android.app.Activity;
import android.os.Bundle;

@ChineseName("我的Activity中文名")
public class MyActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Activity 其他代码...
    }
}

3.2创建生命周期回调类

实现 Application.ActivityLifecycleCallbacks

创建一个实现 Application.ActivityLifecycleCallbacks 接口的类,以记录每个 Activity 的启动时间,并使用反射获取中文名。

import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
import android.util.Log;

public class ActivityLifecycleHandler implements Application.ActivityLifecycleCallbacks {
    private static final String TAG = "ActivityLifecycleHandler";

    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        long startTime = System.currentTimeMillis();
        activity.getWindow().getDecorView().post(() -> {
            long endTime = System.currentTimeMillis();
            long duration = endTime - startTime;
            String activityName = getChineseName(activity);
            Log.d(TAG, activityName + " creation time: " + duration + " ms");
        });
    }

    @Override
    public void onActivityStarted(Activity activity) {}
    @Override
    public void onActivityResumed(Activity activity) {}
    @Override
    public void onActivityPaused(Activity activity) {}
    @Override
    public void onActivityStopped(Activity activity) {}
    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}
    @Override
    public void onActivityDestroyed(Activity activity) {}

    private String getChineseName(Activity activity) {
        ChineseName annotation = activity.getClass().getAnnotation(ChineseName.class);
        if (annotation != null) {
            return annotation.value();
        } else {
            return activity.getClass().getSimpleName();
        }
    }
}

3.3 注册生命周期回调

Application 类中注册生命周期回调:

public class MyApp extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        registerActivityLifecycleCallbacks(new AppLifecycleHandler());
    }
}

3.4 修改 AndroidManifest.xml

确保在 AndroidManifest.xml 中指定自定义的 Application 类:

<application
    android:name=".MyApp"
    ...>
    ...
</application>

3.5持续日志输出

使用 adb logcat 命令捕获启动时间的日志输出。

adb logcat -s AppLifecycleHandler

每次切换页面或启动新的 Activity 时,控制台会输出类似如下的日志信息:

07-04 14:23:45.123 1234-1234/com.example.myapp D/AppLifecycleHandler: MainActivity startup time: 150 ms
07-04 14:23:47.567 1234-1234/com.example.myapp D/AppLifecycleHandler: SettingsActivity startup time: 180 ms
07-04 14:23:47.567 1234-1234/com.example.myapp D/AppLifecycleHandler: 我的Activity中文名 startup time: 180 ms

这些日志显示了每个 Activity 的启动时间。通过这些数据,可以分析和优化应用性能。

4.记录所有 Fragment 启动时间

同样,可以通过覆盖 Fragment 的生命周期方法来记录 Fragment 的启动时间。

4.1使用注解标记中文名

同样地,为 Fragment 使用相同的 ChineseName 注解。

import androidx.fragment.app.Fragment;

@ChineseName("我的Fragment中文名")
public class MyFragment extends Fragment {
    // Fragment 代码...
}

4.2覆盖 Fragment 生命周期方法

首先,创建一个基类 BaseFragment,覆盖 FragmentonCreateView 方法,以记录每个 Fragment 的启动时间。

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;

public class FragmentLifecycleHandler extends FragmentManager.FragmentLifecycleCallbacks {
    private static final String TAG = "FragmentLifecycleHandler";

    @Override
    public void onFragmentViewCreated(@NonNull FragmentManager fm, @NonNull Fragment f, @NonNull View v, @Nullable Bundle savedInstanceState) {
        long startTime = System.currentTimeMillis();
        f.getView().post(() -> {
            long endTime = System.currentTimeMillis();
            long duration = endTime - startTime;
            String fragmentName = getChineseName(f);
            Log.d(TAG, fragmentName + " view creation time: " + duration + " ms");
        });
    }

    private String getChineseName(Fragment fragment) {
        ChineseName annotation = fragment.getClass().getAnnotation(ChineseName.class);
        if (annotation != null) {
            return annotation.value();
        } else {
            return fragment.getClass().getSimpleName();
        }
    }
}

4.3完整代码示例

所有的 Fragment 类继承自 BaseFragment

public class MyFragment extends BaseFragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_my, container, false);
    }
}

4.4持续日志输出

使用 adb logcat 命令捕获启动时间的日志输出。

adb logcat -s FragmentLifecycle

每次加载 Fragment 时,控制台会输出类似如下的日志信息:

07-04 14:23:45.123 1234-1234/com.example.myapp D/FragmentLifecycle: MyFragment startup time: 120 ms

这些日志显示了每个 Fragment 的启动时间。通过这些数据,可以分析和优化应用性能。

5. 使用第三方工具

除了自定义实现外,还有许多第三方工具和库可以帮助测量和优化应用的启动时间。以下是一些常用的工具和库:

5.1 阿里云移动监控(Aliyun Mobile Monitoring)

阿里云移动监控 提供了全面的性能监控解决方案,包括启动时间、崩溃分析、用户行为分析等功能。

使用步骤:
  1. 集成 SDK
    • 在阿里云控制台创建一个项目,并下载阿里云移动监控 SDK。
    • 将 SDK 集成到的 Android 应用中。具体步骤可以参考 阿里云官方文档。
  2. 配置性能监控
    • 在阿里云控制台中配置性能监控,包括启动时间监控和用户行为分析。
  3. 查看性能数据
    • 登录阿里云控制台,访问 阿里云移动监控 部分,可以查看应用的启动时间、崩溃报告以及用户行为分析数据。

5.2 腾讯云移动分析(Tencent Cloud Mobile Analytics)

腾讯云移动分析 提供了全面的应用性能监控和用户行为分析功能,适用于中国国内的应用开发者。

使用步骤:
  1. 集成 SDK
    • 在腾讯云控制台创建一个项目,并下载腾讯云移动分析 SDK。
    • 将 SDK 集成到的 Android 应用中。具体步骤可以参考 腾讯云官方文档.
  2. 配置性能监控
    • 在腾讯云控制台中配置性能监控和用户行为分析功能。
  3. 查看性能数据
    • 登录腾讯云控制台,访问 腾讯云移动分析 部分,可以查看应用的启动时间、崩溃报告以及用户行为数据。

5.3 百度移动统计(Baidu Mobile Statistics)

百度移动统计 提供了应用性能监控和用户行为分析功能,帮助开发者了解应用的性能和用户行为。

使用步骤:
  1. 集成 SDK
    • 在百度统计控制台创建一个项目,并下载百度移动统计 SDK。
    • 将 SDK 集成到的 Android 应用中。具体步骤可以参考 百度统计官方文档.
  2. 配置性能监控
    • 在百度统计控制台中配置性能监控功能和用户行为分析。
  3. 查看性能数据
    • 登录百度统计控制台,访问 百度移动统计 部分,可以查看应用的启动时间、崩溃报告和用户行为数据。

5.3 Android Profiler

Android Profiler 是 Android Studio 提供的一套工具,可以帮助实时监控应用的性能,包括启动时间、内存使用、CPU 使用等。

使用步骤:
  1. 启动 Android Studio Profiler

    • 打开 Android Studio,运行的应用。
    • 选择 View > Tool Windows > Profiler,然后选择的应用进程。
  2. 监控应用启动时间

    • 在 Profiler 窗口中,选择 CPU 视图。
    • 启动应用时,Profiler 会记录启动过程中 CPU 的使用情况,可以帮助了解启动时间及其瓶颈。
  3. 分析性能数据

    • Profiler 提供的时间线视图和详细的性能指标可以帮助识别启动过程中的性能问题。
    • 可以查看应用的活动生命周期、内存使用情况以及 CPU 占用情况,从而找到优化的切入点。

5.4 LeakCanary

LeakCanary 是一个开源的内存泄漏检测库,可以帮助检测和修复内存泄漏,从而间接优化应用的启动时间和整体性能。

使用步骤:
  1. 集成 LeakCanary

    • build.gradle 文件中添加 LeakCanary 的依赖:

      debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.10'
      
  2. 自动检测内存泄漏

    • LeakCanary 会自动监控应用的内存泄漏并在发现泄漏时发出警告。
  3. 修复内存泄漏

    • 根据 LeakCanary 提供的报告,识别并修复内存泄漏问题,从而提高应用的性能和启动速度。

备注

Firebase Performance Monitoring

Firebase Performance Monitoring 是一个由 Google 提供的性能监控工具,它可以帮助开发者监控应用的性能,包括启动时间、网络请求时间等。然而,由于某些 Google 服务在中国大陆可能会受到访问限制,Firebase Performance Monitoring 的功能和数据传输可能会受到影响。

官方地址:

  • Firebase Performance Monitoring 官方文档

总结

使用这些第三方工具,可以更全面地监控和优化应用的启动时间和整体性能。三方库 和 Android Profiler 提供了实时的性能数据和分析功能,而 LeakCanary 可以帮助发现并修复内存泄漏问题。这些工具和库的结合使用,可以帮助提升应用的用户体验和性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/770586.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

医疗器械进销存软件 专业合规的医疗公司器械出入库管理软件

财务管理&#xff1a;财务档案统一管理&#xff0c;有利于科学管理企业资金 财务管理&#xff1a;发票关联业务单据&#xff0c;业财融合&#xff0c;加速财务数字化转型 财务管理&#xff1a;提供收付款功能&#xff0c;加快企业应收账款的回收&#xff0c;降低付款的资金浮…

深圳比创达EMC|EMI电磁干扰行业:从源头到终端的全面解决方案2

深圳比创达EMC&#xff5c;EMI电磁干扰行业&#xff1a;从源头到终端的全面解决方案 在当今电子信息技术日新月异的时代&#xff0c;电磁干扰&#xff08;EMI&#xff09;问题愈发凸显其重要性。EMI电磁干扰行业作为解决这一问题的关键领域&#xff0c;正面临着前所未有的挑战…

带着味蕾去旅行,在“必吃”餐厅里认识一座城

时代不同了&#xff0c;旅游也变了。十多年前的旅游&#xff0c;是文艺青年的诗与远方&#xff0c;生活在别处的荷尔蒙之旅&#xff0c;宁浩拍了部电影叫《心花怒放》&#xff0c;那些年不管是大理、丽江、拉萨、成都&#xff0c;还是张家界&#xff0c;商家最喜欢用的宣传口号…

前端引用vue/element/echarts资源等引用方法Blob下载HTML

前端引用下载vue/element/echarts资源等引用方法 功能需求 需求是在HTML页面中集成Vue.js、Element Plus&#xff08;Element UI的Vue 3版本&#xff09;、ECharts等前端资源&#xff0c;使用Blob下载HTML。 解决方案概述 直接访问线上CDN地址&#xff1a;简单直接&#xff0c…

Fiddler关于Repaly的细节您了解吗?如何重复执行请求?

最近深入的使用了一下Fiddler的Repaly功能&#xff0c;没想到有这么多的细节&#xff0c;不仅可以设置Repaly的次数&#xff0c;还可以无条件地重发选中的请求&#xff0c;而不考虑之前的请求条件或缓存状态。在这里与各位小伙伴分享一下&#xff0c;希望能够帮到大家&#xff…

使用pdf.js在Vue、React中预览Pdf文件,支持PC端、移动端

&#x1f4dd; 使用背景 在前端开发中&#xff0c;有时候我们需要进行pdf文件的预览操作&#xff0c;通过在网上查询&#xff0c;基本都是一下几种常见的预览pdf文件的方法&#xff1a; 实现方案效果HTML 标签iframe 标签iOS&#xff1a;只能展示第一页&#xff0c;多页不能展…

conda安装cudatoolkit=11.6 (不在default channel的package)

问题描述 众所周知&#xff0c;conda有3个频道 - defaults - pytorch - conda-forge 直接执行 conda install cudatoolkit11.6发现不在当前频道&#xff0c; 添加频道 conda config --add channels conda-forge显示当前频道列表 conda config --show channels从conda-for…

深化产教融合“桥梁”作用!蓝卓携手宁波4大院校共育数智人才

建强“三支队伍”赋能新质生产力&#xff0c;为进一步加强新时代教师队伍建设改革&#xff0c;促进人才培养能力和服务企业能力“双提升”&#xff0c;7月2日&#xff0c;“2024企业实践工业互联网职业教育师资培训班”在蓝卓顺利开班。 来自宁波城市职业技术学院、宁波职业技…

【算法】插入排序

一、算法图示二、算法思想三、代码实现四、算法效率分析4.1 更新运行时长函数4.2 与选择排序对比五、算法改进5.1 结论分析5.2 改进算法图示5.3 算法说明5.4 代码实现5.5 算法效率对比1)算法升级前后对比2)与选择排序对比一、算法图示 二、算法思想 图示以7 1 5 4 1 8 11为例…

桌面记笔记的软件:能加密的笔记app

在日常生活和工作中&#xff0c;很多人都有记笔记的习惯。无论是记录会议要点、学习心得&#xff0c;还是生活中的点滴灵感&#xff0c;笔记都是我们不可或缺的好帮手。然而&#xff0c;传统的纸笔记录方式逐渐不能满足现代人的需求&#xff0c;因为纸质笔记不易保存、查找困难…

idea 内存参数修改不生效问题解决 VM参数设置不生效解决

很多人配置idea 内存参数&#xff0c;怎么配置都不生效&#xff0c;主要原因是配置文件用的不是你修改的那个。 系统环境变量中的这个才是你真正要修改的配置文件。 找到并修改后保存&#xff0c;重启idea就可生效

NodeJS 蔬菜自产零售混合销售平台-计算机毕业设计源码10149

摘 要 随着移动互联网的快速发展&#xff0c;购物方式也发生了巨大的变化。蔬菜作为消费者生活中必不可少的商品之一&#xff0c;在移动互联网时代也迎来了新的购物方式——购物小程序。购物小程序是一种基于手机应用平台的轻量级应用程序&#xff0c;用户可以通过它方便地浏览…

opencv编译报错OpenCV does not recognize MSVC_VERSION “1940“

具体如下: CMake Warning at cmake/OpenCVDetectCXXCompiler.cmake:182 (message):OpenCV does not recognize MSVC_VERSION "1940". Cannot set OpenCV_RUNTIME Call Stack (most recent call first):CMakeLists.txt:174 (include) 打开源码\opencv\sources\cmak…

springboot私人诊所管理系统-计算机毕业设计源码93887

摘要 随着科技的不断发展和医疗服务的日益普及&#xff0c;私人诊所管理系统成为现代医疗管理的重要组成部分。该系统通过引入计算机技术和互联网平台&#xff0c;为患者提供方便快捷的就诊方式&#xff0c;同时也为诊所、医院提供高效的资源管理和服务优化的途径。本文将介绍私…

Jlink调试的时候提示擦除超时,programming failed @ address 0x0804000

如果能正常下载进单片机&#xff0c;但是调试提示上面的信息。是keil的问题&#xff0c;把所有断点都取消了再调试就好了

Mybatis入门の基础操作

1 Mybatis概述 MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生Map使用简单的 XML 或注解&#xff0c;将接口和 Java 的 POJOs(Plain Old Java Objects,普通的…

JavaScript中的this指向

1. 全局环境下的this 在全局环境中&#xff08;在浏览器中是window对象&#xff0c;在Node.js中是global对象&#xff09;&#xff0c;this指向全局对象。 console.log(this window); // 在浏览器中为true console.log(this.document ! undefined); // true&#xff0c;因为…

若依前后端分离 前端路由登录页 如何进行跳转

路由守卫&#xff0c;看这篇文章 http://t.csdnimg.cn/HkypThttp://t.csdnimg.cn/HkypT

LLM推理引擎性能评测对比:vllm、lmdeploy、tensorrt-llm

01 简介 在当今LLM时代&#xff0c;大模型的效果已经取得了长足的进步&#xff0c;逐渐成为业务流程中的重要部分&#xff0c;因此对性能进行评估变得至关重要&#xff0c;由于目前LLM推理都需要比较高级的GPU&#xff0c;使得LLM推理成本高&#xff0c;因此在不同使用场景下…