perfetto 官方文档翻译

Perfetto 翻译-trace分析-PerfettoSQL

2023-11-06  本文已影响0人  David_zhou

前言:虽然有翻译软件,虽然有chatgpt,毕竟语言隔阂,对这个工具还是一知半解,因此想通过翻译的方式和大家来一起学习下Perfetto这个强大的工具

目录

#####################以下分割线#####################
英文原文在这里

PerfettoSQL 标准库

本页主要介绍了 PerfettoSQL 标准库。

简介

PerfettoSQL标准库是一个由领域专家贡献的库,包括了表,视图,函数和宏的存储库,使查询traces更容易。它的设计在很大程度上受到Python,C++和Java等语言标准库的启发。

标准库的一些用途包括:

  1. 作为一种共享和常用查询的方式,无需复制/粘贴大量 SQL。
  2. 在trace中的详细数据提高抽象级别。标准库中的许多模块将低级跟踪概念(例如切片、轨道)转换为开发人员可能更熟悉的概念,例如对于 Android 开发人员:应用程序启动、binder transactions 等。

标准库模块可以如下集成:

-- Include all tables/views/functions from the android.startup.startups
-- module in the standard library.
INCLUDE PERFETTO MODULE android.startup.startups;

-- Use the android_startups table defined in the android.startup.startups
-- module.
SELECT *
FROM android_startups;

有关导入模块的更多信息,请参阅该 INCLUDE PERFETTO MODULE 语句的语法文档。

概览

Views/tables
Name Import Description
thread_slice common.slices All thread slices with data about thread, thread track and process
process_slice common.slices All process slices with data about process track and process
android_anrs android.anrs List of all ANRs that occurred in the trace (one row per ANR)
android_battery_charge android.battery Battery charge at timestamp
android_battery_stats_state android.battery_stats View of human readable battery stats counter-based states
android_battery_stats_event_slices android.battery_stats View of slices derived from battery_stats events
android_binder_metrics_by_process android.binder Count Binder transactions per process
android_sync_binder_metrics_by_txn android.binder Breakdown synchronous binder transactions per txn
android_sync_binder_thread_state_by_txn android.binder Aggregated thread_states on the client and server side per binder txn This builds on the data from
android_sync_binder_blocked_functions_by_txn android.binder Aggregated blocked_functions on the client and server side per binder txn This builds on the data from
android_async_binder_metrics_by_txn android.binder Breakdown asynchronous binder transactions per txn
android_binder_txns android.binder Breakdown asynchronous binder transactions per txn
android_io_f2fs_counter_stats android.io Aggregates f2fs IO and latency stats by counter name
android_io_f2fs_write_stats android.io Aggregates f2fs_write stats by inode and thread
android_io_f2fs_aggregate_write_stats android.io Aggregates f2fs write stats
android_monitor_contention android.monitor_contention Contains parsed monitor contention slices
android_monitor_contention_chain android.monitor_contention Contains parsed monitor contention slices with the parent-child relationships
android_monitor_contention_chain_thread_state android.monitor_contention Note that we only span join the duration where the lock was actually held and contended
android_monitor_contention_chain_thread_state_by_txn android.monitor_contention Aggregated thread_states on the 'blocking thread', the thread holding the lock
android_monitor_contention_chain_blocked_functions_by_txn android.monitor_contention Aggregated blocked_functions on the 'blocking thread', the thread holding the lock
android_network_packets android.network_packets Android network packet events (from android
android_process_metadata android.process_metadata Data about packages running on the process
android_screenshots android.screenshots Screenshot slices, used in perfetto UI
android_startups android.startup.startups All activity startups in the trace by startup id
android_startup_processes android.startup.startups Maps a startup to the set of processes that handled the activity start
android_startup_threads android.startup.startups Maps a startup to the set of threads on processes that handled the activity start
android_thread_slices_for_all_startups android.startup.startups All the slices for all startups in trace
android_statsd_atoms android.statsd Statsd atoms
chrome_scrolls chrome.chrome_scrolls Defines slices for all of the individual scrolls in a trace based on the LatencyInfo-based scroll definition
chrome_scrolling_intervals chrome.chrome_scrolls Defines slices for all of scrolls intervals in a trace based on the scroll definition in chrome_scrolls
chrome_cpu_power_slice chrome.cpu_powerups The CPU power transitions in the trace
chrome_cpu_power_first_sched_slice_after_powerup chrome.cpu_powerups The Linux scheduler slices that executed immediately after a CPU power up
chrome_cpu_power_post_powerup_slice chrome.cpu_powerups A table holding the slices that executed within the scheduler slice that ran on a CPU immediately after power-up
chrome_cpu_power_first_toplevel_slice_after_powerup chrome.cpu_powerups The first top-level slice that ran after a CPU power-up
chrome_histograms chrome.histograms A helper view on top of the histogram events emitted by Chrome
chrome_interactions chrome.interactions All critical user interaction events, including type and table with associated metrics
chrome_page_loads chrome.page_loads Chrome page loads, including associated high-level metrics and properties
chrome_janky_event_latencies_v3 chrome.scroll_jank.scroll_jank_intervals Selects EventLatency slices that correspond with janks in a scroll
chrome_janky_frame_presentation_intervals chrome.scroll_jank.scroll_jank_intervals Frame presentation interval is the delta between when the frame was supposed to be presented and when it was actually presented
chrome_scroll_stats chrome.scroll_jank.scroll_jank_intervals Scroll jank frame presentation stats for individual scrolls
chrome_scroll_jank_intervals_v3 chrome.scroll_jank.scroll_jank_intervals Defines slices for all of janky scrolling intervals in a trace
chrome_gesture_scroll_updates chrome.scroll_jank.scroll_jank_v3 Grabs all gesture updates with respective scroll ids and start/end timestamps, regardless of being coalesced
chrome_presented_gesture_scrolls chrome.scroll_jank.scroll_jank_v3 Scroll updates, corresponding to all input events that were converted to a presented scroll update
chrome_scroll_updates_with_deltas chrome.scroll_jank.scroll_jank_v3 Associate every trace_id with it's perceived delta_y on the screen after prediction
chrome_gesture_scroll_event_latencies chrome.scroll_jank.scroll_jank_v3 Extract event latency timestamps, to later use it for joining with gesture scroll updates, as event latencies don't have trace ids associated with it
chrome_full_frame_view chrome.scroll_jank.scroll_jank_v3 Join presented gesture scrolls with their respective event latencies based on
chrome_full_frame_delta_view chrome.scroll_jank.scroll_jank_v3 Join deltas with EventLatency data
chrome_merged_frame_view chrome.scroll_jank.scroll_jank_v3 Group all gestures presented at the same timestamp together in a single row
chrome_frame_info_with_delay chrome.scroll_jank.scroll_jank_v3 View contains all chrome presented frames during gesture updates while calculating delay since last presented which usually should equal to
chrome_vsyncs chrome.scroll_jank.scroll_jank_v3 Calculate
chrome_janky_frames_no_cause chrome.scroll_jank.scroll_jank_v3 Filter the frame view only to frames that had missed vsyncs
chrome_janky_frames_no_subcause chrome.scroll_jank.scroll_jank_v3 Janky frame information including the jank cause
chrome_janky_frames chrome.scroll_jank.scroll_jank_v3 Finds all causes of jank for all janky frames, and a cause of sub jank if the cause of jank was GPU related
chrome_unique_frame_presentation_ts chrome.scroll_jank.scroll_jank_v3 Counting all unique frame presentation timestamps
chrome_janky_frames_percentage chrome.scroll_jank.scroll_jank_v3 Dividing missed frames over total frames to get janky frame percentage
chrome_frames_per_scroll chrome.scroll_jank.scroll_jank_v3 Number of frames and janky frames per scroll
chrome_causes_per_scroll chrome.scroll_jank.scroll_jank_v3 Scroll jank causes per scroll
chrome_deltas_presented_frame_scroll_update_ids chrome.scroll_jank.scroll_offsets All of the presented frame scroll update ids
chrome_scroll_input_offsets chrome.scroll_jank.scroll_offsets The raw coordinates and pixel offsets for all input events which were part of a scroll
chrome_presented_scroll_offsets chrome.scroll_jank.scroll_offsets The scrolling offsets for the actual (applied) scroll events
chrome_speedometer_measure chrome.speedometer Augmented slices for Speedometer measurements
chrome_speedometer_iteration chrome.speedometer Slice that covers one Speedometer iteration
chrome_java_views chrome.tasks A list of slices corresponding to operations on interesting (non-generic) Chrome Java views
chrome_scheduler_tasks chrome.tasks A list of tasks executed by Chrome scheduler
chrome_tasks chrome.tasks A list of "Chrome tasks": top-level execution units (e
chrome_vsync_intervals chrome.vsync_intervals A simple table that checks the time between VSync (this can be used to determine if we're refreshing at 90 FPS or 60 FPS)
pkvm_hypervisor_events pkvm.hypervisor Events when CPU entered hypervisor
Functions
Name Import Return type Description
formatted_arg common.args STRING Returns the formatted value of a given argument
earliest_timestamp_for_counter_track common.counters LONG Timestamp of first counter value in a counter
guess_cpu_size common.cpus STRING Guess size of CPU
extract_int_metadata common.metadata LONG Extracts an int value with the given name from the metadata table
has_parent_slice_with_name common.slices BOOL Checks if slice has an ancestor with provided name
slice_count common.slices INT Count slices with specified name
slice_name_from_id common.slices STRING Given a slice id, returns the name of the slice
human_readable_thread_state_name common.thread_states STRING Returns a human-readable name for a thread state
is_spans_overlapping common.timestamps BOOL Checks whether two spans are overlapping
spans_overlapping_dur common.timestamps INT Return the overlapping duration between two spans
ns common.timestamps INT Converts a duration in seconds to nanoseconds, which is the default representation of time durations in trace processor
us common.timestamps INT Converts a duration in microseconds to nanoseconds, which is the default representation of time durations in trace processor
ms common.timestamps INT Converts a duration in millseconds to nanoseconds, which is the default representation of time durations in trace processor
seconds common.timestamps INT Converts a duration in seconds to nanoseconds, which is the default representation of time durations in trace processor
minutes common.timestamps INT Converts a duration in minutes to nanoseconds, which is the default representation of time durations in trace processor
hours common.timestamps INT Converts a duration in hours to nanoseconds, which is the default representation of time durations in trace processor
days common.timestamps INT Converts a duration in days to nanoseconds, which is the default representation of time durations in trace processor
android_battery_stats_counter_to_string android.battery_stats STRING Converts a battery_stats counter value to human readable string
android_extract_android_monitor_contention_blocking_thread android.monitor_contention STRING Extracts the blocking thread from a slice name
android_extract_android_monitor_contention_blocking_tid android.monitor_contention INT Extracts the blocking thread tid from a slice name
android_extract_android_monitor_contention_blocking_method android.monitor_contention STRING Extracts the blocking method from a slice name
android_extract_android_monitor_contention_short_blocking_method android.monitor_contention STRING Extracts a shortened form of the blocking method name from a slice name
android_extract_android_monitor_contention_blocked_method android.monitor_contention STRING Extracts the monitor contention blocked method from a slice name
android_extract_android_monitor_contention_short_blocked_method android.monitor_contention STRING Extracts a shortened form of the monitor contention blocked method name from a slice name
android_extract_android_monitor_contention_waiter_count android.monitor_contention INT Extracts the number of waiters on the monitor from a slice name
android_extract_android_monitor_contention_blocking_src android.monitor_contention STRING Extracts the monitor contention blocking source location from a slice name
android_extract_android_monitor_contention_blocked_src android.monitor_contention STRING Extracts the monitor contention blocked source location from a slice name
android_standardize_slice_name android.slices STRING Some slice names have params in them
android_sum_dur_for_startup_and_slice android.startup.startups INT Returns duration of startup for slice name
android_sum_dur_on_main_thread_for_startup_and_slice android.startup.startups INT Returns duration of startup for slice name on main thread
Table Functions
Name Import Description
counter_percentiles_for_time_range common.percentiles All percentiles (range 1-100) for counter track ID in a given time range
counter_percentiles_for_track common.percentiles All percentiles (range 1-100) for counter track ID
thread_state_summary_for_interval common.thread_states Returns an aggregation of thread states (by state and cpu) for a given interval of time for a given thread
android_binder_outgoing_graph android.binder Returns a DAG of all outgoing binder txns from a process
android_binder_incoming_graph android.binder Returns a DAG of all incoming binder txns from a process
android_binder_graph android.binder Returns a graph of all binder txns in a trace
android_monitor_contention_graph android.monitor_contention Returns a DAG of all Java lock contentions in a process
总结
模块:通用
common.args

函数

formatted_arg:返回给定参数的格式化值。与 EXTRACT_ARG 类似,但它不是返回原始值,而是返回根据“value_type”列格式化的值(例如,对于布尔值,EXTRACT_ARG将返回 0 或 1,而 FORMATTED_ARG 将返回“true”或“false”)。

返回值:STRING,参数的格式化值。

Argument Type Description
arg_set_id INT Id of the arg set.
key STRING Key of the argument.
common.counters

函数

earliest_timestamp_for_counter_track:计数器中第一个计数器值的时间戳。

返回值:LONG,第一个计数器值的时间戳。如果不存在,则为 Null。

Argument Type Description
arg_set_id INT Id of the arg set.
key STRING Key of the argument.
common.cpus

函数

guess_cpu_size:猜测 CPU 的大小核。在一些多核设备上,内核是异构的,分为两个或多个“大小核”。在典型情况下,设备可能有 8 个内核,其中 4 个是“小核”(低功耗和低性能),4 个是“大核”(高功率和高性能)。此函数尝试将给定的 CPU 索引映射到相关描述符。对于同构系统,这将返回 NULL。

返回:STRING,大小核描述信息('little'、'mid'、'big'等),如果我们没有足够的信息,则返回 NULL。

Argument Type Description
cpu_index INT Index of the CPU whose size we will guess.
common.metadata

函数
extract_int_metadata:从元数据表中提取具有指定名称的 int 值。
返回值:LONG,int_value给定名称。如果没有此类条目,则为 NULL。

Argument Type Description
name STRING The name of the metadata entry.
common.percentiles

表函数
counter_percentiles_for_time_range:给定时间范围内track ID的计数器 的所有百分位数(范围 1-100)。百分位数的计算公式为:1.将计数器中每个值的时间持续时间总和除以范围内计数器的持续时间。这给了我们 percentile_for)value (DOUBLE)。2. 通过取每个百分位数的下限来获取每个百分位数,按结果 percentile 分组,并从每个 percentile_for_value 分组的值中分出最小值。当我们向下舍入时,采用 MIN 可确保数据最可靠。3. 通过从每个分段的较高百分位数中获取最小值来填补百分位数中可能的缺口。

Argument Type Description
counter_track_id INT Id of the counter track.
start_ts LONG Timestamp of start of time range.
end_ts LONG Timestamp of end of time range.
Column Description
percentile All of the numbers from 1 to 100.
value Value for the percentile.

counter_percentiles_for_track:计数器跟踪 ID 的所有百分位数(范围 1-100)。

Argument Type Description
counter_track_id INT Id of the counter track.
Column Description
percentile All of the numbers from 1 to 100.
value Value for the percentile.
common.slices

视图/表

thread_slice,视图
所有线程切片,包含有关线程、线程跟踪和进程的数据。如果可能,请使用可用的视图函数来筛选此视图。

Column Description
id Alias for slice.id.
type Alias for slice.type.
ts Alias for slice.ts.
dur Alias for slice.dur.
category Alias for slice.category.
name Alias for slice.name.
track_id Alias for slice.track_id.
track_name Alias for thread_track.name.
thread_name Alias for thread.name.
utid Alias for thread.utid.
tid Alias for thread.tid
process_name Alias for process.name.
upid Alias for process.upid.
pid Alias for process.pid.
depth Alias for slice.depth.
parent_id Alias for slice.parent_id.
arg_set_id Alias for slice.arg_set_id.
thread_ts Alias for slice.thread_ts.
thread_dur Alias for slice.thread_dur.

process_slice, 视图

所有进程切片,包含有关进程跟踪和进程的数据。如果可能,请使用可用的视图函数来筛选此视图。

Column Description
id Alias for slice.id.
type Alias for slice.type.
ts Alias for slice.ts.
dur Alias for slice.dur.
category Alias for slice.category.
name Alias for slice.name.
track_id Alias for slice.track_id.
track_name Alias for process_track.name.
process_name Alias for process.name.
upid Alias for process.upid.
pid Alias for process.pid.
depth Alias for slice.depth.
parent_id Alias for slice.parent_id.
arg_set_id Alias for slice.arg_set_id.
thread_ts Alias for slice.thread_ts.
thread_dur Alias for slice.thread_dur.

函数

has_parent_slice_with_name:检查切片是否有特定名称的父slice。

返回值:BOOL,parent_name是否是的父slice的名字。

Argument Type Description
id INT Id of the slice to check parents of.
parent_name STRING Name of potential ancestor slice.

slice_count:对具有指定名称的切片进行计数。
返回值:INT,特定名称的切片数量。

Argument Type Description
slice_glob STRING Name of the slices to counted.
common.thread_states

函数
human_readable_thread_state_name:返回可读的线程状态名称。
返回值:STRING,可读的线程状态名称。

Argument Type Description
id LONG the slice id which we need the name for.

表函数

thread_state_summary_for_interval:返回给定线程在给定时间间隔内的线程状态(按状态和 cpu)的汇总。

Argument Type Description
ts INT The start of the interval.
dur INT The duration of the interval.
utid INT The utid of the thread.
Column Description
state Human-readable thread state name.
raw_state Raw thread state name, alias of thread_state.state.
cpu_type The type of CPU if available (e.g. "big" / "mid" / "little").
cpu The CPU index.
blocked_function The name of the kernel function execution is blocked in.
dur The total duration.
common.timestamps

函数
is_spans_overlapping:检查两个跨度是否重叠。
返回值:BOOL,两个跨度是否重叠。

Argument Type Description
ts1 LONG Start of first span.
ts_end1 LONG End of first span.
ts2 LONG Start of second span.
ts_end2 LONG End of second span

spans_overlapping_dur:返回两个跨度之间的重叠持续时间。如果持续时间小于 0 或没有交集,则返回 0

返回值:INT,重叠持续时间

Argument Type Description
ts1 LONG Timestamp of first slice start.
dur1 LONG Duration of first slice.
ts2 LONG Timestamp of second slice start.
dur2 LONG Duration of second slice.

ns:将持续时间(以秒为单位)转换为纳秒,这是跟踪处理器中持续时间的默认表示形式。和其他函数保持一致性。
返回值:INT,持续时间(以纳秒为单位)。

Argument Type Description
nanos INT Time duration in seconds.

us:将持续时间(以微秒为单位)转换为纳秒,纳秒是跟踪处理器中持续时间的默认表示形式。
返回值:INT,持续时间(以纳秒为单位)。

Argument Type Description
micros INT Time duration in microseconds.

ms 将持续时间(以毫秒为单位)转换为纳秒,纳秒跟踪处理器中持续时间的默认表示形式。
返回值:INT,持续时间(以纳秒为单位)。

Argument Type Description
millis INT Time duration in milliseconds.

seconds:将持续时间(以秒为单位)转换为纳秒,纳秒是跟踪处理器中持续时间的默认表示形式。
返回值:INT,持续时间(以纳秒为单位)。

Argument Type Description
seconds INT Time duration in seconds.

minutes: 将持续时间(以分钟为单位)转换为纳秒,纳秒是跟踪处理器中持续时间的默认表示形式。
返回值:INT,持续时间(以纳秒为单位)。

Argument Type Description
minutes INT Time duration in minutes.

hours:将持续时间(以小时为单位)转换为纳秒,纳秒是跟踪处理器中持续时间的默认表示形式。
返回值:INT,持续时间(以纳秒为单位)。

Argument Type Description
hours INT Time duration in hours.

days:将持续时间(以天为单位)转换为纳秒,纳秒是跟踪处理器中持续时间的默认表示形式。
返回值:INT,持续时间(以纳秒为单位)。

Argument Type Description
days INT Time duration in days.
模块:android
android.anrs

视图/表

android_anrs, 视图

跟踪中发生的所有 ANR 的列表(每个 ANR 一行)

Column Description
process_name Name of the process that triggered the ANR.
pid PID of the process that triggered the ANR.
upid UPID of the process that triggered the ANR.
error_id UUID of the ANR (generated on the platform).
ts Timestamp of the ANR.
subject Subject line of the ANR.
android.battery

视图/表

android_battery_charge, 视图

在特定时间戳的电量

Column Description
ts Timestamp.
current_avg_ua Current average micro ampers.
capacity_percent Current capacity percentage.
charge_uah Current charge in micro ampers.
current_ua Current micro ampers.
android.battery_stats

视图/表

android_battery_stats_state,视图
可读的基于计数器的电池统计信息的状态视图。这些被 BatteryStats 记录为位图,其中每个“类别”在任何时间都有唯一的值。

Column Description
ts Timestamp in nanoseconds.
dur The duration the state was active.
track_name The name of the counter track.
value The counter value as a number.
value_name The counter value as a human-readable string.

android_battery_stats_event_slices, 视图
从battery_stats事件派生的切片视图。电池统计信息将所有事件记录为瞬间,但有些事件可能会以“+”或“-”前缀指示某些事件是开始还是停止。任务、最前面的app、前台app或长时间的唤醒等事件包含这些详细信息,并允许在跟踪中找到的即时事件之间绘制切片。例如,我们可能会在“battery_stats.top”上看到类似以下内容的事件: -top=10215:“com.google.android.apps.nexuslauncher” ,此视图将找到以开始('+top')的,以(“=”后面的所有内容)结束的切片,它从事件中计算时间戳和持续时间,并提取详细信息,如下所示:track_name='battery_stats.top' str_value='com.google.android.apps.nexuslauncher' int_value=10215

Column Description
track_name The battery stats track name.
ts Timestamp in nanoseconds.
dur The duration of the event.
str_value The string part of the event identifier.
int_value The integer part of the event identifier.

函数

android_battery_stats_counter_to_string:将battery_stats计数器值转换为可读的字符串。

返回值:STRING,计数器值的可读名称。

Argument Type Description
track STRING The counter track name (e.g. 'battery_stats.audio').
value FLOAT The counter value.
android.binder

视图/表

txn 应该是transaction的缩写

android_binder_metrics_by_process, 视图

计算每个进程的 Binder 事务数。

Column Description
process_name Name of the process that started the binder transaction.
pid PID of the process that started the binder transaction.
slice_name Name of the slice with binder transaction.
event_count Number of binder transactions in process in slice.

android_sync_binder_metrics_by_txn, 视图

细分每个 transaction 的同步 binder 事务。它返回每个 binder 事务有关的客户端和服务器端的数据。

Column Description
aidl_name name of the binder interface if existing.
binder_txn_id slice id of the binder txn.
client_process name of the client process.
client_thread name of the client thread.
client_upid Upid of the client process.
client_utid Utid of the client thread.
client_tid Tid of the client thread.
client_ts timestamp of the client txn.
client_dur dur of the client txn.
client_oom_score oom score of the client process at the start of the txn.
is_main_thread Whether the txn was initiated from the main thread of the client process.
binder_reply_id slice id of the binder reply.
server_process name of the server process.
server_thread name of the server thread.
server_upid Upid of the server process.
server_utid Utid of the server thread.
server_tid Tid of the server thread.
server_ts timestamp of the server txn.
server_dur dur of the server txn.
server_oom_score oom score of the server process at the start of the reply.

android_sync_binder_thread_state_by_txn、视图
每个客户端和服务器端的 binder transaction 聚合thread_states,这来自在 |android_sync_binder_metrics_by_txn|对于事务的每个端(客户端和服务器),它返回所有线程状态持续时间的聚合总和。|thread_state_type|列表示给定的“聚合thread_state”行是在客户端还是在服务器端。“binder_txn”是客户端,“binder_reply”是服务器端。

Column Description
binder_txn_id slice id of the binder txn
binder_reply_id slice id of the binder reply
thread_state_type whether thread state is on the txn or reply side
thread_state a thread_state that occurred in the txn
thread_state_dur aggregated dur of the
thread_state_count aggregated count of the

android_sync_binder_blocked_functions_by_txn, 视图
每个 binder transaction 在客户端和服务器端的聚合blocked_functions 这建立在 |android_sync_binder_metrics_by_txn|对于事务的每个端(客户端和服务器),它返回所有内核阻塞函数持续时间的聚合总和。|thread_state_type|列表示给定的“聚合blocked_function”行是在客户端还是服务器端。“binder_txn”是客户端,“binder_reply”是服务器端。

Column Description
binder_txn_id slice id of the binder txn
binder_reply_id slice id of the binder reply
thread_state_type whether thread state is on the txn or reply side
blocked_function blocked kernel function in a thread state
blocked_function_dur aggregated dur of the
blocked_function_count aggregated count of the

android_async_binder_metrics_by_txn, VIEW
细分每个异步 transaction 的 Binder 事务。它返回有关每个异步 binder 事务的客户端和服务器端的数据。

ColumnDescriptionaidl_namename of the binder interface if existing.binder_txn_idslice id of the binder txn.client_processname of the client process.client_threadname of the client thread.client_upidUpid of the client process.client_utidUtid of the client thread.client_tidTid of the client thread.client_tstimestamp of the client txn.client_durdur of the client txn.client_oom_scoreoom score of the client process at the start of the txn.is_main_threadWhether the txn was initiated from the main thread of the client process.binder_reply_idslice id of the binder reply.server_processname of the server process.server_threadname of the server thread.server_upidUpid of the server process.server_utidUtid of the server thread.server_tidTid of the server thread.server_tstimestamp of the server txn.server_durdur of the server txn.server_oom_scoreoom score of the server process at the start of the reply.

android_binder_txns, 视图
细分每个 transaction 的异步 Binder 事务。它返回有关每个 binder 事务异步的客户端和服务器端的数据。

Column Description
aidl_name name of the binder interface if existing.
binder_txn_id slice id of the binder txn.
client_process name of the client process.
client_thread name of the client thread.
client_upid Upid of the client process.
client_utid Utid of the client thread.
client_tid Tid of the client thread.
client_ts timestamp of the client txn.
client_dur dur of the client txn.
client_oom_score oom score of the client process at the start of the txn.
is_main_thread Whether the txn was initiated from the main thread of the client process.
binder_reply_id slice id of the binder reply.
server_process name of the server process.
server_thread name of the server thread.
server_upid Upid of the server process.
server_utid Utid of the server thread.
server_tid Tid of the server thread.
server_ts timestamp of the server txn.
server_dur dur of the server txn.
server_oom_score oom score of the server process at the start of the reply.
is_sync whether the txn is synchronous or async (oneway).

Table Functions 表函数
android_binder_outgoing_graph :返回进程中所有outgoing transaction 的binder 的有向无环图。图的根源是发出 txntransaction 的线程,图从以下位置流出:thread -> server_process -> AIDL 接口 -> AIDL 方法。每个节点的权重表示server_process中的CPU执行时间。

Argument Type Description
upid STRING Upid of process to generate an outgoing graph for.
Column Description
pprof BYTES Pprof of outgoing binder txns.

android_binder_incoming_graph:返回进程的所有incoming binder transactions的 有向无环图。图的根源是发出 transaction 的客户端,图流自:client_process -> AIDL 接口 -> AIDL 方法。每个节点的权重表示server_process中的执行时间。

Argument Type Description
upid STRING Upid of process to generate an outgoing graph for.
Column Description
pprof BYTES Pprof of outgoing binder txns.

android_binder_graph 返回trace中binder transaction的图形。节点是client_process和server_process。每个节点的权重表示server_process中的执行时间。

Argument Type Description
min_client_oom_score INT Matches txns from client_processes greater than or equal to the OOM score.
max_client_oom_score INT Matches txns from client_processes less than or equal to the OOM score.
min_server_oom_score INT Matches txns to server_processes greater than or equal to the OOM score.
max_server_oom_score INT Matches txns to server_processes less than or equal to the OOM score.
Column Description
pprof BYTES Pprof of binder txns.
android.dvfs

视图/表

android_dvfs_counters, 视图

具有持续时间的 Dvfs 计数器。

Column Description
name {'type': 'STRING', 'desc': 'Counter name.'}
ts {'type': 'INT', 'desc': 'Timestamp when counter value changed.'}
value {'type': 'INT', 'desc': 'Counter value.'}
dur {'type': 'INT', 'desc': 'Counter duration.'}

android_dvfs_counter_stats, 表
用于统计信息的 dvfs 计数器聚合切片

Column Description
name {'type': 'STRING', 'desc': 'Counter name on which all the other values are aggregated on.'}
max {'type': 'INT', 'desc': 'Max of all counter values for the counter name.'}
min {'type': 'INT', 'desc': 'Min of all counter values for the counter name.'}
dur {'type': 'INT', 'desc': 'Duration between the first and last counter value for the counter name.'}
wgt_avg {'type': 'FLOAT', 'desc': 'Weighted avergate of all the counter values for the counter name.'}

android_dvfs_counter_residency, 视图

常驻的 dvfs 计数器聚合切片

Column Description
slice_id {'type': 'INT', 'desc': 'Id of the corresponding slice in slices table.'}
cpu {'type': 'INT', 'desc': 'CPU that entered hypervisor.'}
ts {'type': 'INT', 'desc': 'Timestamp when CPU entered hypervisor (in nanoseconds).'}
dur {'type': 'INT', 'desc': 'How much time CPU spent in hypervisor (in nanoseconds).'}
reason {'type': 'STRING', 'desc': 'Reason for entering hypervisor (e.g. host_hcall, host_mem_abort), or NULL if unknown.'}
android.io

表/视图

android_io_f2fs_counter_stats, 视图
按计数器名称统计的 f2fs IO 和延迟聚合信息。

Column Description
counter_name {'type': 'STRING', 'desc': 'Counter name on which all the other values are aggregated on.'}
counter_sum {'type': 'INT', 'desc': 'Sum of all counter values for the counter name.'}
counter_max {'type': 'INT', 'desc': 'Max of all counter values for the counter name.'}
counter_min {'type': 'INT', 'desc': 'Min of all counter values for the counter name.'}
counter_dur {'type': 'INT', 'desc': 'Duration between the first and last counter value for the counter name.'}
counter_count {'type': 'INT', 'desc': 'Count of all the counter values for the counter name.'}
counter_avg {'type': 'DOUBLE', 'desc': 'Avergate of all the counter values for the counter name.'}

android_io_f2fs_write_stats, 视图

按 inode 和线程聚合f2fs_write统计信息。

Column Description
utid {'type': 'INT', 'desc': 'Utid of the thread.'}
tid {'type': 'INT', 'desc': 'Tid of the thread.'}
thread_name {'type': 'STRING', 'desc': 'Name of the thread.'}
upid {'type': 'INT', 'desc': 'Upid of the process.'}
pid {'type': 'INT', 'desc': 'Pid of the process.'}
process_name {'type': 'STRING', 'desc': 'Name of the thread.'}
ino {'type': 'INT', 'desc': 'Inode number of the file being written.'}
dev {'type': 'INT', 'desc': 'Device node number of the file being written.'}
bytes {'type': 'BYTES', 'desc': 'Total number of bytes written on this file by the
write_count {'type': 'INT', 'desc': 'Total count of write requests for this file.'}

android_io_f2fs_aggregate_write_stats, 视图

聚合 f2fs 写入统计信息。计算不同的数据点、总写入操作数和写入的字节数

Column Description
total_write_count {'type': 'INT', 'desc': 'Total number of writes in the trace.'}
distinct_processes {'type': 'INT', 'desc': 'Number of distinct processes.'}
total_bytes_written {'type': 'INT', 'desc': 'Total number of bytes written.'}
distinct_device_count {'type': 'INT', 'desc': 'Count of distinct devices written to.'}
distict_inode_count {'type': 'INT', 'desc': 'Count of distinct inodes written to.'}
distinct_thread_count {'type': 'INT', 'desc': 'Count of distinct threads writing.'}
android.monitor_contention

视图/表

android_monitor_contention, 表
包含分析过的锁竞争切片。

ColumnDescriptionblocking_method{'type': None, 'desc': 'Name of the method holding the lock.'}blocked_methhod{'type': None, 'desc': 'Name of the method trying to acquire the lock.'}short_blocking_method{'type': None, 'desc': 'Blocking_method without arguments and return types.'}short_blocked_method{'type': None, 'desc': 'Blocked_method without arguments and return types.'}blocking_src{'type': None, 'desc': 'File location of blocking_method in form filename:linenumber.'}blocked_src{'type': None, 'desc': 'File location of blocked_method in form filename:linenumber.'}waiter_count{'type': None, 'desc': 'Zero indexed number of threads trying to acquire the lock.'}blocking_utid{'type': None, 'desc': 'Utid of thread holding the lock.'}blocking_thread_name{'type': None, 'desc': 'Thread name of thread holding the lock.'}upid{'type': None, 'desc': 'Upid of process experiencing lock contention.'}process_name{'type': None, 'desc': 'Process name of process experiencing lock contention.'}id{'type': None, 'desc': 'Slice id of lock contention.'}ts{'type': None, 'desc': 'Timestamp of lock contention start.'}dur{'type': None, 'desc': 'Duration of lock contention.'}track_id{'type': None, 'desc': 'Thread track id of blocked thread.'}is_blocked_main_thread{'type': None, 'desc': 'Whether the blocked thread is the main thread.'}is_blocking_main_thread{'type': None, 'desc': 'Whether the blocking thread is the main thread.'}binder_reply_id{'type': None, 'desc': 'Slice id of binder reply slice if lock contention was part of a binder txn.'}binder_reply_ts{'type': None, 'desc': 'Timestamp of binder reply slice if lock contention was part of a binder txn.'}binder_reply_tid{'type': None, 'desc': 'Tid of binder reply slice if lock contention was part of a binder txn.'}
包含具有父子关系的分析过的锁竞争切片。

Column Description
parent_id {'type': None, 'desc': 'Id of monitor contention slice blocking this contention.'}
blocking_method {'type': None, 'desc': 'Name of the method holding the lock.'}
blocked_methhod {'type': None, 'desc': 'Name of the method trying to acquire the lock.'}
short_blocking_method {'type': None, 'desc': 'Blocking_method without arguments and return types.'}
short_blocked_method {'type': None, 'desc': 'Blocked_method without arguments and return types.'}
blocking_src {'type': None, 'desc': 'File location of blocking_method in form filename:linenumber.'}
blocked_src {'type': None, 'desc': 'File location of blocked_method in form filename:linenumber.'}
waiter_count {'type': None, 'desc': 'Zero indexed number of threads trying to acquire the lock.'}
blocking_utid {'type': None, 'desc': 'Utid of thread holding the lock.'}
blocking_thread_name {'type': None, 'desc': 'Thread name of thread holding the lock.'}
upid {'type': None, 'desc': 'Upid of process experiencing lock contention.'}
process_name {'type': None, 'desc': 'Process name of process experiencing lock contention.'}
id {'type': None, 'desc': 'Slice id of lock contention.'}
ts {'type': None, 'desc': 'Timestamp of lock contention start.'}
dur {'type': None, 'desc': 'Duration of lock contention.'}
track_id {'type': None, 'desc': 'Thread track id of blocked thread.'}
is_blocked_main_thread {'type': None, 'desc': 'Whether the blocked thread is the main thread.'}
is_blocking_main_thread {'type': None, 'desc': 'Whether the blocking thread is the main thread.'}
binder_reply_id {'type': None, 'desc': 'Slice id of binder reply slice if lock contention was part of a binder txn.'}
binder_reply_ts {'type': None, 'desc': 'Timestamp of binder reply slice if lock contention was part of a binder txn.'}
binder_reply_tid {'type': None, 'desc': 'Tid of binder reply slice if lock contention was part of a binder txn.'}
child_id {'type': None, 'desc': 'Id of monitor contention slice blocked by this contention.'}

android_monitor_contention_chain_thread_state、表格
请注意,我们只统计了锁实际持有和竞争的持续时间。这可能小于其他锁等待线程比第一个其他锁等待线程更早获得锁时“等待”锁的持续时间。

Column Description
parent_id {'type': None, 'desc': 'Id of slice blocking the blocking_thread.'}
blocking_method {'type': None, 'desc': 'Name of the method holding the lock.'}
blocked_methhod {'type': None, 'desc': 'Name of the method trying to acquire the lock.'}
short_blocking_method {'type': None, 'desc': 'Blocking_method without arguments and return types.'}
short_blocked_method {'type': None, 'desc': 'Blocked_method without arguments and return types.'}
blocking_src {'type': None, 'desc': 'File location of blocking_method in form filename:linenumber.'}
blocked_src {'type': None, 'desc': 'File location of blocked_method in form filename:linenumber.'}
waiter_count {'type': None, 'desc': 'Zero indexed number of threads trying to acquire the lock.'}
blocking_utid {'type': None, 'desc': 'Utid of the blocking
blocking_thread_name {'type': None, 'desc': 'Thread name of thread holding the lock.'}
upid {'type': None, 'desc': 'Upid of process experiencing lock contention.'}
process_name {'type': None, 'desc': 'Process name of process experiencing lock contention.'}
id {'type': None, 'desc': 'Slice id of lock contention.'}
ts {'type': None, 'desc': 'Timestamp of the blocking
dur {'type': None, 'desc': 'Duration of lock contention.'}
track_id {'type': None, 'desc': 'Thread track id of blocked thread.'}
is_blocked_main_thread {'type': None, 'desc': 'Whether the blocked thread is the main thread.'}
is_blocking_main_thread {'type': None, 'desc': 'Whether the blocking thread is the main thread.'}
binder_reply_id {'type': None, 'desc': 'Slice id of binder reply slice if lock contention was part of a binder txn.'}
binder_reply_ts {'type': None, 'desc': 'Timestamp of binder reply slice if lock contention was part of a binder txn.'}
binder_reply_tid {'type': None, 'desc': 'Tid of binder reply slice if lock contention was part of a binder txn.'}
state {'type': None, 'desc': 'Thread state of the blocking thread.'}
blocked_function {'type': None, 'desc': 'Blocked kernel function of the blocking thread.'}

android_monitor_contention_chain_thread_state_by_txn,视图
“阻塞线程”(保持锁的线程)上的聚合thread_states。这建立在 |android_monitor_contention_chain|对于每个锁竞争切片,它返回阻塞线程上所有线程状态的聚合总和。请注意,此数据仅适用于锁上的第一个等待锁的线程。

Column Description
id {'type': 'INT', 'desc': 'Slice id of the monitor contention.'}
thread_state {'type': 'STRING', 'desc': 'A
thread_state_dur {'type': 'INT', 'desc': 'Total time the blocking thread spent in the
thread_state_count {'type': 'INT', 'desc': 'Count of all times the blocking thread entered

android_monitor_contention_chain_blocked_functions_by_txn, 视图
“阻塞线程”上的聚合blocked_functions,即保持锁的线程。这建立在 |android_monitor_contention_chain|对于每个锁竞争线程,它返回阻塞线程上所有内核阻塞函数持续时间的总和。请注意,此数据仅适用于锁上的等锁的线程。

Column Description
id {'type': 'INT', 'desc': 'Slice id of the monitor contention.'}
blocked_function {'type': 'STRING', 'desc': 'Blocked kernel function in a thread state in the blocking thread during the contention.'}
blocked_function_dur {'type': 'INT', 'desc': 'Total time the blocking thread spent in the
blocked_function_count {'type': 'INT', 'desc': 'Count of all times the blocking thread executed the

函数

android_extract_android_monitor_contention_blocking_thread 从切片名称中提取阻塞线程
返回: STRING, 阻塞线程

Argument Type Description
slice_name STRING Name of slice

android_extract_android_monitor_contention_blocking_tid 从切片名称中提取阻塞线程 tid

返回: INT, 阻塞线程 tid

Argument Type Description
slice_name STRING Name of slice

android_extract_android_monitor_contention_blocking_method 从切片名称中提取阻塞方法

返回: STRING, 阻塞线程

Argument Type Description
slice_name STRING Name of slice

android_extract_android_monitor_contention_short_blocking_method 从切片名称中提取阻塞方法名称的缩写形式。简写模式将不会有参数和返回类型。

返回: STRING, 阻塞线程

Argument Type Description
slice_name STRING Name of slice

android_extract_android_monitor_contention_blocked_method 从切片名称中锁竞争阻塞的方法
返回: STRING, 阻塞线程

Argument Type Description
slice_name STRING Name of slice

android_extract_android_monitor_contention_short_blocked_method 从片名称中提取锁竞争阻塞的方法名称的缩写形式。缩短形式不包含参数和返回类型。
返回: STRING, 阻塞线程

Argument Type Description
slice_name STRING Name of slice

android_extract_android_monitor_contention_waiter_count 从切片名称中提取锁上的等待线程数
返回值:INT,锁上的等待线程数

Argument Type Description
slice_name STRING Name of slice

android_extract_android_monitor_contention_blocking_src:从切片名称中提取锁竞争阻塞的源代码位置

返回: STRING, 阻塞线程

Argument Type Description
slice_name STRING Name of slice

android_extract_android_monitor_contention_blocked_src 从切片名称中提前发生过锁竞争阻塞的源代码位置

返回: STRING, 阻塞线程

Argument Type Description
slice_name STRING Name of slice
android.network_packets

视图/表

android_network_packets, 视图

Android 网络数据包事件(来自android.network_packets数据源)。

Column Description
ts {'type': 'INT', 'desc': 'Timestamp in nanoseconds.'}
dur {'type': 'INT', 'desc': 'Duration (non-zero only in aggregate events)'}
track_name {'type': 'STRING', 'desc': 'The track name (interface and direction)'}
package_name {'type': 'STRING', 'desc': 'Traffic package source (or uid=$X if not found)'}
iface {'type': 'STRING', 'desc': 'Traffic interface name (linux interface name)'}
direction {'type': 'STRING', 'desc': "Traffic direction ('Transmitted' or 'Received')"}
packet_count {'type': 'INT', 'desc': 'Number of packets in this event'}
packet_length {'type': 'INT', 'desc': 'Number of bytes in this event (wire size)'}
packet_transport {'type': 'STRING', 'desc': 'Transport used for traffic in this event'}
packet_tcp_flags {'type': 'INT', 'desc': 'TCP flags used by tcp frames in this event'}
socket_tag {'type': 'STRING', 'desc': 'The Android traffic tag of the network socket'}
socket_uid {'type': 'INT', 'desc': 'The Linux user id of the network socket'}
local_port {'type': 'INT', 'desc': 'The local port number (for udp or tcp only)'}
remote_port {'type': 'INT', 'desc': 'The remote port number (for udp or tcp only)'}
packet_icmp_type {'type': 'INT', 'desc': '1-byte ICMP type identifier.'}
packet_icmp_code {'type': 'INT', 'desc': '1-byte ICMP code identifier.'}
android.process_metadata

视图/表

android_process_metadata, 表

有关进程上运行的app的数据。

Column Description
upid {'type': 'INT', 'desc': 'Process upid.'}
process_name {'type': 'STRING', 'desc': 'Process name.'}
package_name {'type': 'STRING', 'desc': 'Name of the packages running in this process.'}
version_code {'type': 'INT', 'desc': 'Package version code.'}
debuggable {'type': 'INT', 'desc': 'Whether package is debuggable.'}
android.screenshots

视图/表

android_screenshots, 表

屏幕截图切片,用于perfetto UI。

Column Description
id {'type': 'INT', 'desc': 'Slice id.'}
ts {'type': 'INT', 'desc': 'Slice timestamp.'}
dur {'type': 'INT', 'desc': 'Slice duration, should be typically 0 since screeenshot slices are of instant type.'}
name {'type': 'STRING', 'desc': 'Slice name.'}
android.slices

函数
android_standardize_slice_name 某些切片名称中包含参数。此函数会删除它们,以便可以按名称进行聚合。一些示例包括: - 锁定/等待锁切片。该名称包括锁争用在代码中的位置。该部分将被删除。- DrawFrames/ooFrame。该名称还包括帧号。- Apk/oat/dex 加载:删除 apk 的名称
返回值:STRING,简体名称。

Argument Type Description
name STRING The raw slice name.
android.startup.startups

视图/表

android_startups 表格

按启动 ID 跟踪中的所有启动的activity。根据平台版本/内容由不同的脚本填充。

Column Description
startup_id {'type': 'INT', 'desc': 'Startup id.'}
ts {'type': 'INT', 'desc': 'Timestamp of startup start.'}
ts_end {'type': 'INT', 'desc': 'Timestamp of startup end.'}
dur {'type': 'INT', 'desc': 'Startup duration.'}
package {'type': 'STRING', 'desc': 'Package name.'}
startup_type {'type': 'STRING', 'desc': 'Startup type.'}

android_startup_processes, 表格
将启动映射到处理activity启动的进程集合。绝大多数情况应该是一个单一的过程。但是,该进程可能会在活动启动期间终止并重新启动。

Column Description
startup_id {'type': 'INT', 'desc': 'Startup id.'}
upid {'type': 'INT', 'desc': 'Upid of process on which activity started.'}
startup_type {'type': 'INT', 'desc': 'Type of the startup.'}

android_startup_threads, 视图

将启动映射到处理activity启动的进程上的线程集合。

Column Description
startup_id {'type': 'INT', 'desc': 'Startup id.'}
ts {'type': 'INT', 'desc': 'Timestamp of start.'}
dur {'type': 'INT', 'desc': 'Duration of startup.'}
upid {'type': 'INT', 'desc': 'Upid of process involved in startup.'}
utid {'type': 'INT', 'desc': 'Utid of the thread.'}
thread_name {'type': 'STRING', 'desc': 'Name of the thread.'}
is_main_thread {'type': 'BOOL', 'desc': 'Thread is a main thread.'}

android_thread_slices_for_all_startups, 视图
trace中所有启动的所有切片。通常,不应使用此视图。请改用与由此表创建的启动切片相关的视图函数之一。

Column Description
startup_ts {'type': 'INT', 'desc': 'Timestamp of startup.'}
startup_ts_end {'type': 'INT', 'desc': 'Timestamp of startup end.'}
startup_id {'type': 'INT', 'desc': 'Startup id.'}
utid {'type': 'INT', 'desc': 'UTID of thread with slice.'}
thread_name {'type': 'STRING', 'desc': 'Name of thread.'}
is_main_thread {'type': 'BOOL', 'desc': 'Whether it is main thread.'}
arg_set_id {'type': 'INT', 'desc': 'Arg set id.'}
slice_id {'type': 'INT', 'desc': 'Slice id.'}
slice_name {'type': 'STRING', 'desc': 'Name of slice.'}
slice_ts {'type': 'INT', 'desc': 'Timestamp of slice start.'}
slice_dur {'type': 'INT', 'desc': 'Slice duration.'}

函数
android_sum_dur_for_startup_and_slice:返回切片名称的启动持续时间。对所有启动切片的持续时间按名字求和汇总。
返回值:INT,持续时间总和。

Argument Type Description
startup_id LONG Startup id.
slice_name STRING Slice name.

android_sum_dur_on_main_thread_for_startup_and_slice 返回主线程上切片名称的启动持续时间。仅在主线程上对所有启动切片的持续时间按照名字汇总。
返回值:INT,持续时间总和。

Argument Type Description
startup_id LONG Startup id.
slice_name STRING Slice name.
android.statsd

视图/表

android_statsd_atoms 视图

Statsd 原子。包含 statsd atom 即时事件的切片表的子集。

Column Description
id {'type': 'INT', 'desc': 'Unique identifier for this slice.'}
type {'type': 'STRING', 'desc': 'The name of the "most-specific" child table containing this row.'}
ts {'type': 'INT', 'desc': 'The timestamp at the start of the slice (in nanoseconds).'}
dur {'type': 'INT', 'desc': 'The duration of the slice (in nanoseconds).'}
arg_set_id {'type': 'INT', 'desc': 'The id of the argument set associated with this slice.'}
thread_instruction_count {'type': 'INT', 'desc': 'The value of the CPU instruction counter at the start of the slice. This column will only be populated if thread instruction collection is enabled with track_event.'}
thread_instruction_delta {'type': 'INT', 'desc': 'The change in value of the CPU instruction counter between the start and end of the slice. This column will only be populated if thread instruction collection is enabled with track_event.'}
track_id {'type': 'INT', 'desc': 'The id of the track this slice is located on.'}
category {'type': 'STRING', 'desc': 'The "category" of the slice. If this slice originated with track_event, this column contains the category emitted. Otherwise, it is likely to be null (with limited exceptions).'}
name {'type': 'STRING', 'desc': 'The name of the slice. The name describes what was happening during the slice.'}
depth {'type': 'INT', 'desc': 'The depth of the slice in the current stack of slices.'}
stack_id {'type': 'INT', 'desc': 'A unique identifier obtained from the names of all slices in this stack. This is rarely useful and kept around only for legacy reasons.'}
parent_stack_id {'type': 'INT', 'desc': 'The stack_id for the parent of this slice. Rarely useful.'}
parent_id {'type': 'INT', 'desc': 'The id of the parent (i.e. immediate ancestor) slice for this slice.'}
thread_ts {'type': 'INT', 'desc': 'The thread timestamp at the start of the slice. This column will only be populated if thread timestamp collection is enabled with track_event.'}
thread_dur {'type': 'INT', 'desc': 'The thread time used by this slice. This column will only be populated if thread timestamp collection is enabled with track_event.'}
Module: chrome

省略

Module: experimental

省略

Module: pkvm

省略

#####################以上分割线#####################

后记:
1 本次主要使用百度翻译,虽然被骂,但至少翻译这个工具降低了门槛。
2 英文文档中的长难句真的是又长又难,基于百度的翻译,然后自己再调整下,水平实在有限。
3 技术背景知识不够,有些专有名词不知道怎么翻译,也不知道百度翻译的是否准确,功夫在诗外。
4 万事开头难,中间难不难,还不知道。中间的事后面再说,正确一天翻译一篇。
5 虽然可能会有人不屑,但总要有人去做不起眼的小事。
6 google 厉害,这个perfetto 工具也很厉害。君子善假于物也。
7 工具的使用是最简单的入门,背后还有更多的东西值得学习。
8 水平实在有限,闻过则喜,希望有更多的人反馈,期待更好的建议

上一篇下一篇

猜你喜欢

热点阅读