「 毫秒级 」的应用启动速度评测

2020-11-17 15:39:31 浏览数 (1)

前言

启动速度是一项重要的应用性能指标。以手机输入法为例,用户每次尝试键入时,均会直观感知到输入法键盘的调起速度,若速度过慢则会频繁影响用户体验。

为了能够更准确地获取到键盘调起速度的具体数据,小编编写了基于Python视频及图像处理模块的评测脚本,下面以其中部分函数为例,为大家介绍一下实现思路和流程。

键盘调起自动化

首先需要确认的是,在手机上执行输入法切换与键盘调起等操作的自动化命令——我们可以在找出设备屏幕上的相应坐标后,通过以下adb命令进行实现:

代码语言:javascript复制
def turn_up_swtich(self):
  # 切换到百度输入法
  inputmethod_pkgnames_list = ["com.baidu.input/.ImeService", "com.sohu.inputmethod.sogou/.SogouIME"]
  command_swtichInput = "adb shell ime set "   inputmethod_pkgnames_list[0]
  os.system(command_swtichInput)
  # 点击输入框,尝试调起键盘
  command_turnUp = "adb shell input swipe 500 500 500 500 50"
  os.system(command_turnUp)
  # 关闭百度输入法键盘
  command_turnDown = "adb shell input swipe 660 750 660 750 50"
  os.system(command_turnDown)
  # 切换到搜狗输入法
  command_swtichInput = "adb shell ime set "   inputmethod_pkgnames_list[1]
  os.system(command_swtichInput)

其后,我们通过一个简单的多进程应用,将键盘调起的过程以视频形式记录。为便于后续的视频处理,需要在录制前开启手机“开发者选项”中的“指针位置”与“显示触摸操作”。

代码语言:javascript复制
# 视频录制命令
def start_screenrecord(self):
  command = "adb shell screenrecord /sdcard/Movies/ScreenCaptures/SDvideo_data.mp4 --time-limit 5 --size 720x1280"
  os.system(command)

# 搜狗输入法键盘调起
def click_action(self):
  time.sleep(0.5)
  command_turnUp = "adb shell input swipe 500 500 500 500 50"
  os.system(command_turnUp)

# 多进程使键盘调起与视频录制同时进行
def make_video(self, video_path, runNum):
  p1 = Process(target=self.start_screenrecord)
  p2 = Process(target=self.click_action)
  p1.start()
  p2.start()
  p2.join()
  p1.join()
  time.sleep(0.5)
  # 导出并保存视频
  dest_path = video_path   "/"   str(runNum)   ".mp4"
  self.get_file("adb pull /sdcard/Movies/ScreenCaptures/SDvideo_data.mp4 ", dest_path)
  return dest_path

这样,通过一个“切换输入法”、“键盘调起并录屏”的循环,即可得到多个视频素材,以期在后续的视频处理、结果输出时,通过多个数据的均值来消弭误差:

代码语言:javascript复制
def run(self):
# 启动带有输入框的测试app
  command_start = "adb shell am start -n com.sogou.inputtest/.MainActivity"
  os.system(command_start)
  for runNum in range(0,50):
    # 每次循环先切换到其他输入法,再进行搜狗输入法键盘调起录制
    self.turn_up_swtich()
    dest_path = self.make_video(self.video_path, runNum)
    # 视频处理解析
    self.parse(dest_path ,runNum)
  # 输出耗时数据
  return self.turnUp_speed

视频处理解析

针对视频素材,需要通过视频处理模块sk-video将其逐帧解析,并对每帧画面加以识别——得到“点击输入框,尝试调起键盘”与“键盘调起完成”两个事件所发生画面之间的帧数差值,用来计算键盘调起耗时。

下面给出完整方法,对其中判断环节的说明可见注释及后续内容:

代码语言:javascript复制
# 视频解析——传入视频文件与当前循环次数
def parse(self, video_file, runNum):
  # 以60帧加载处理视频
  output_dict = {"-r": str(60)}
  evaluation_video = skvideo.io.vreader(video_file, outputdict=output_dict)
  # 当前帧数
  num = 0
  has_keydown = False
  self.is_turn_up_img = None
  for frame in evaluation_video:
    # 获取每帧画面宽高
    self.img_size_width = int(frame.shape[1])
    self.img_size_height = int(frame.shape[0])
    # 画面中搜狗输入法标识区域
    target_img = frame[self.target_pos]
    # 画面中屏幕顶部色块区域
    block_img = frame[self.block_pos]
    # 根据色块颜色变化情况判断是否发生按下输入框
    if self.is_key_down(block_img, num):
      has_keydown = True
      # 记录发生按下输入框画面的帧数
      is_key_down_num = num  
    if has_keydown:
      # 由发生按下输入框开始,保存标识处图片
      cv2.imwrite(".\key\cand\turnup_"   str(runNum)   "\"   str(num)   ".png", target_img)
      # 标识移动到预设位置(已完成调起键盘),记录画面帧数
      if self.is_turn_up(target_img, num):
        has_turn_up_num = num - 1
        # 计算耗时,写入列表
        turnup_time = int(has_turn_up_num - is_key_down_num)*16.6
        self.turnUp_speed.append(turnup_time)
        return 
      num  = 1

首先,根据设备在执行自动化键盘调起时的表现——模拟按下输入框时,屏幕顶部色块的颜色变红(如下图),即可通过图像处理模块cv2,对画面相应坐标处的颜色变化进行监控,由此定位到视频中哪一帧画面发生了“点击输入框,尝试调起键盘”:

代码语言:javascript复制
def is_key_down(self, block_img):
    # 识别色块处颜色变化
    r, g, b = cv2.split(block_img)
    red_num = 0
    for x in range(0, r.shape[0], 5):
      for y in range(0, r.shape[1], 5):
        if r[x, y] > 200 and g[x, y] < 100 and b[x, y] < 100:
          red_num  = 1
    total_num = r.shape[0] / 5 * r.shape[1]
    down_filter_num = total_num / 20
    up_filter_num = total_num / 100
    # 根据色块颜色(变红)判断发生按下
    if self.key_state['is_key_down']:
      if red_num < up_filter_num:
        self.key_state['is_key_down'] = False
    else:
      if red_num > down_filter_num:
        self.key_state['is_key_down'] = True
        return True
    return False

同理,以“搜狗输入法标识完全上升到相应位置”为键盘调起完成的标志,在键盘调起、标识逐渐上升的过程中(如下图),对每帧画面中相应坐标处的颜色变化进行识别,以期得到此刻帧数:

代码语言:javascript复制
# 搜狗标识颜色变化识别
def is_turn_up(self, target_img):
    b, g, r = cv2.split(target_img)
    speed_num = 0
    for x in range(0, r.shape[0], 5):
      for y in range(0, r.shape[1], 5):
        if b[x, y] < 200 and g[x, y] < 200 and r[x, y] < 200:
          speed_num  = 1
    if self.is_turn_up_img:
      if speed_num == self.is_turn_up_img:
          return True
      # 以标识图片颜色变化达到一定程度为限
      if speed_num >= 2:
        self.is_turn_up_img = speed_num
    return False

最终,将本轮脚本执行得出的两个帧数间差值乘以每帧耗时(16.67ms)后写入结果列表,并在预设的循环次数完成后,取得列表中的数据均值,便是当前输入法键盘调起速度的评测结果了。

结语

相比于主观感知,根据这样的应用启动(键盘调起)速度评测实现方案,无疑能够得出更为准确、可靠的数据结果,而此方案亦可推广到其他各式应用的评测当中。欢迎各位一同沟通、学习。

0 人点赞