Power Profiling: MQTT on Android (1)

2023-12-14 23:38
文章标签 android mqtt power profiling

本文主要是介绍Power Profiling: MQTT on Android (1),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Power Profiling: MQTT on Android

Introduction

Recently I’ve been doing a lot with MQTT on Android, in particular because it’s such a good fit. Not only can it be used to provide immediate push notification capability, but it also provides low latency, guaranteed messaging over fragile networks and efficient distribution to one or many receivers. Even better, it does all this with small message sizes (minimising the amount of bytes flowing over the wire) and low power usage.

The other great thing about MQTT is that there’s loads of information about it on the web. The specification is fully available, it’s about to be an open standard and it’s also been fairly well adopted by the hobby & hacker crowd, so there’s loads of blogs and tutorials all about it.

One thing I have noticed though, is that, while most people who’ve used MQTT know that it uses extremely low amounts of power on mobile devices, I couldn’t find any definitive power figures. It’s mostly just anecdotal evidence, and so I thought I’d try collecting some. This post details what I did & the results I found.

What was I testing?

Basically it’s a very simple application that calls a custom Android wrapper around a standard Java MQTT client offered by IBM (the one that currently ships with WebSphere MQ Telemetry, for those in the know). All the MQTT work is done in it’s own thread and messages flow in and out between this and the test application through Handlers. It’s not really worthy of a screenshot, but if you’re really keen, you can find one here.

The custom wrapper is one that I’ve created for some things I’ve been doing at work, so unfortunately I’m not able to post the code (right now); but if you imagine a couple of Handlers for getting messages in and out, an Alarm Manager for sending Keep-Alives and some special error handling, you wouldn’t be far wrong.

How did I test it?

I’ve written up a separate post here on the generic approach I used to capture and process the power usage data. In terms of specifics for this testing, I used the Android application described above along with a simple desktop application that was used to send data to / receive data from the Android application. The tests were kicked off manually by myself, either by clicking a button in the Android app or by starting a process in the desktop application, but the timing of events was captured automatically – which allowed me to normalise for any delays from me starting things off.

Caveats / Specifics

  • The power profiling was performed on my HTC Desire, running Android 2.2 – Build 2.33.161.2 CL284385.
  • Throughout this article I refer to the power usage in terms of % Battery / Hour. This refers to the % of the fully charged capacity of my phone’s battery that is used per hour. My phone has a standard Li-Ion battery that is rated at: 1400mAh & 3.7V.
  • The tool I used to capture the power usage data (PowerTutor) uses real data, combined with a power usage model for some aspects. This model has been tailored against the type of device I used for this testing and is reported to be accurate to within 0.8% on average, with a 2.5% margin of error. If you’re interested, you can find out more here.
  • I’ve tried my best to produce correct, consistent and usable results; however I am human and so there’s a chance I have made mistakes somewhere. As such, these figures shouldn’t be treated as Gospel, but I would expect them to be representative of what you could expect to see.

Results

Keep Alive

The first thing I tested was how much power does it take to simply maintain an open MQTT connection, with no messages flowing over the wire. To do this, the MQTT client needs to send a keep-alive message every so often to maintain the connection channel and also to let the server know it’s still connected. I tried a number of different keep-alive intervals and the results are summarised in the table below:

 % Battery / Hour
Keep Alive
(Seconds)
3GWifi
600.776412780.0119021
1200.388844570.0062861
2400.155684610.00283991
4800.077922080.00134018

 
As you can see, the figures are fantastically low. 3G is probably of the most interest to people, and, even with a relatively short keep-alive interval of 60 seconds, it only costs ~0.8% of the phone’s battery per hour to maintain an open connection; with immediate push notification capability (one of the big selling points of MQTT on Android). And it’s an inverse relationship after that – with a doubling of the keep-alive interval, halving the battery usage.

Personally, I tend to go for a keep-alive interval of 240 seconds; which provides timely detection of the disconnection of the client/server balanced against suitably low power usage (~0.16% per hour on 3G).

As a brief aside: It was suggested to me that some mobile providers will purge a 3G TCP/IP connection if there’s no activity on it for over 10 minutes, however I did try a keep-alive interval of 960 seconds (16 minutes) and everything seemed to behave correctly. Though I guess this could be provider specific (I’m with Vodafone).

Sending

The next thing I looked at was sending messages from the phone. I found it somewhat difficult to get sensible & consistent figures for sending a single message and so I decided to scale up to sending 1024 messages, of 1 byte a piece, as quickly as possible. This also helped to emphasise the difference between the different Qualities of Service (QoS – assured delivery level). The results are shown in the graphs below:

Note: You can click & drag on an area of the graph to zoom to it. Single click anywhere to zoom back out.

3G – Send 1024 x 1 byte messages – Total mW
mW
0
50
100
150
200
250
0
200
400
600
800
1000
1200
 QoS 2
 QoS 1
 QoS 0
 1 second period
Wifi – Send 1024 x 1 byte messages – Total mW
mW
0
50
100
150
200
250
0
100
200
300
400
500
 QoS 2
 QoS 1
 QoS 0
 1 second period

As you can see, the QoS 0 messages complete the fastest, followed by the QoS 1 and then the QoS 2. This is because the higher the Quality of Service, the more reliable the message delivery, and this has an associated overhead and delay; as it requires additional messages to flow between the client and server to confirm delivery.

Unfortunately this makes it kind of hard to compare the different levels for battery usage, as QoS 0 uses more power per second (most of this is made up of CPU usage), but for a short amount of time, whereas QoS 1 & QoS 2 use much less power per second, but each for much longer. However, if we use a certain amount of poetic licence, we can extrapolate from the data to say how much battery would it cost to send continuously at each level for an hour, how many message would be sent in this time and from that get the comparative battery cost per message*, which I’ve outlined in the tables below:

3G
QoS% Battery / HourMessages / Hour% Battery / Message *
QoS 015.126144000.000025
QoS 116.87239380.000705
QoS 217.66154890.001140
Wifi
QoS% Battery / HourMessages / Hour% Battery / Message *
QoS 02.023686400.000005
QoS 10.93261440.000036
QoS 20.89137040.000065

 
* – This is a bit of a silly metric. Firstly, you wouldn’t tend to use MQTT like this, it’s more focused on providing an open channel for push notification and a more sporadic style of message sending & receiving. Secondly, there is a fixed cost in having the Wifi or 3G active and so the actual cost of just sending a single message would be higher. However these figures do serve to indicate the difference between the three qualities of service and hopefully give you an indication of the battery usage involved.

If you’re interested in seeing how the power usage breaks down into the different categories (CPU & 3G/Wifi) you can click here for some more pretty graphs.

Receiving

After sending, the next thing I looked at was receiving messages on the phone. To be consistent with the sending results, I sent 1024 messages, of 1 byte a piece, to the phone, as quickly as possible. The results are shown in the graphs below:

3G – Receive 1024 x 1 byte messages – Total mW
mW
0
50
100
150
200
250
300
350
0
200
400
600
800
1000
 QoS 2
 QoS 1
 QoS 0
 1 second period
Wifi – Receive 1024 x 1 byte messages – Total mW
mW
0
50
100
150
200
250
300
350
0
100
200
300
400
500
 QoS 2
 QoS 1
 QoS 0
 1 second period

Again we can see that the QoS 0 messages complete the fastest, followed by the QoS 1 and then QoS 2 (for the same reasons mentioned above). It takes slightly longer for all the messages to be received and so the power per second for each QoS is much more comparable, as the CPU load is spread out. However, to be consistent, I have extrapolated the data as before into the tables below.

A couple of other things of notice are the two erroneous patterns in the QoS 2 flows. For 3G we see the message receiving stop for about 20 seconds before continuing, and for Wifi we briefly see a large spike in power usage about half way through. Unfortunately I don’t have anything to explain this, the connection doesn’t drop and there’s nothing immediately obvious. I’m going to repeat these tests when I get time and I expect this will turn out to be a one off anomaly, but for the moment I thought you might appreciate the experimental authenticity :)

3G
QoS% Battery / HourMessages / Hour% Battery / Message *
QoS 016.03354460.000452
QoS 117.48275100.000635
QoS 215.80135520.001166
Wifi
QoS% Battery / HourMessages / Hour% Battery / Message *
QoS 00.59646730.000009
QoS 10.70329140.000021
QoS 20.86172260.000050

Again, if you’re interested in seeing how the power usage breaks down into the different categories (CPU & 3G/Wifi) you can find them by clicking here.

Connect & Wait

Finally, I thought I’d just briefly include a couple of graphs showing the general shape of creating a connection and leaving it running in the background (i.e. the initial connect and subsequent keep-alives, with a 60 seconds keep-alive interval):

Note: These are stacked graphs. CPU on top of 3G / Wifi.

3G – Connect & Wait
mW
0
20
40
60
80
100
120
140
0
200
400
600
800
1000
 3G
 CPU
 1 second period
Wifi – Connect & Wait
mW
0
20
40
60
80
100
120
140
0
25
50
75
100
125
 Wifi
 CPU
 1 second period

What next?

This has been a relatively shallow foray into power profiling MQTT on Android and now I’ve done it I can think of a whole host of other things that I’m interested in doing. Things such as:

  • Testing the effect of message size on sending & receiving.
  • Testing power usage when running on fragile networks that keep dropping & being re-established.
  • Testing more realistic usage scenarios – e.g. messages flowing much more sparsely and/or at less predictable intervals.
  • Comparing MQTT with it’s possible alternatives, e.g. HTTP, C2DM, etc. Although it may be difficult to create a scenario where they all do the same thing so that they can be measured equally.
  • Open sourcing the code I’ve created – this is something I need to figure out with work, but, if possible, I’d love to get the code I used out there. Not only because I think people would find it really useful to have an Android MQTT component they could just drop into their projects, but also so that people could repeat the tests I’ve done here and try out new scenarios they’ve thought up themselves.

Just need to find the time :)

So, hopefully you found that interesting and maybe useful. If you have any comments, questions or suggestions, I’d be happy to hear them – but please do keep in mind the things I mentioned in the Caveats section above :)

 

 

转载自: http://stephendnicholas.com/archives/219

这篇关于Power Profiling: MQTT on Android (1)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/494310

相关文章

Java MQTT实战应用

《JavaMQTT实战应用》本文详解MQTT协议,涵盖其发布/订阅机制、低功耗高效特性、三种服务质量等级(QoS0/1/2),以及客户端、代理、主题的核心概念,最后提供Linux部署教程、Sprin... 目录一、MQTT协议二、MQTT优点三、三种服务质量等级四、客户端、代理、主题1. 客户端(Clien

如何在Spring Boot项目中集成MQTT协议

《如何在SpringBoot项目中集成MQTT协议》本文介绍在SpringBoot中集成MQTT的步骤,包括安装Broker、添加EclipsePaho依赖、配置连接参数、实现消息发布订阅、测试接口... 目录1. 准备工作2. 引入依赖3. 配置MQTT连接4. 创建MQTT配置类5. 实现消息发布与订阅

Android DataBinding 与 MVVM使用详解

《AndroidDataBinding与MVVM使用详解》本文介绍AndroidDataBinding库,其通过绑定UI组件与数据源实现自动更新,支持双向绑定和逻辑运算,减少模板代码,结合MV... 目录一、DataBinding 核心概念二、配置与基础使用1. 启用 DataBinding 2. 基础布局

Android ViewBinding使用流程

《AndroidViewBinding使用流程》AndroidViewBinding是Jetpack组件,替代findViewById,提供类型安全、空安全和编译时检查,代码简洁且性能优化,相比Da... 目录一、核心概念二、ViewBinding优点三、使用流程1. 启用 ViewBinding (模块级

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

MQTT SpringBoot整合实战教程

《MQTTSpringBoot整合实战教程》:本文主要介绍MQTTSpringBoot整合实战教程,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录MQTT-SpringBoot创建简单 SpringBoot 项目导入必须依赖增加MQTT相关配置编写

基于C#实现MQTT通信实战

《基于C#实现MQTT通信实战》MQTT消息队列遥测传输,在物联网领域应用的很广泛,它是基于Publish/Subscribe模式,具有简单易用,支持QoS,传输效率高的特点,下面我们就来看看C#实现... 目录1、连接主机2、订阅消息3、发布消息MQTT(Message Queueing Telemetr

Android NDK版本迭代与FFmpeg交叉编译完全指南

《AndroidNDK版本迭代与FFmpeg交叉编译完全指南》在Android开发中,使用NDK进行原生代码开发是一项常见需求,特别是当我们需要集成FFmpeg这样的多媒体处理库时,本文将深入分析A... 目录一、android NDK版本迭代分界线二、FFmpeg交叉编译关键注意事项三、完整编译脚本示例四

Android与iOS设备MAC地址生成原理及Java实现详解

《Android与iOS设备MAC地址生成原理及Java实现详解》在无线网络通信中,MAC(MediaAccessControl)地址是设备的唯一网络标识符,本文主要介绍了Android与iOS设备M... 目录引言1. MAC地址基础1.1 MAC地址的组成1.2 MAC地址的分类2. android与I

Android 实现一个隐私弹窗功能

《Android实现一个隐私弹窗功能》:本文主要介绍Android实现一个隐私弹窗功能,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 效果图如下:1. 设置同意、退出、点击用户协议、点击隐私协议的函数参数2. 《用户协议》、《隐私政策》设置成可点击的,且颜色要区分出来res/l