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:
60 | 0.77641278 | 0.0119021 |
120 | 0.38884457 | 0.0062861 |
240 | 0.15568461 | 0.00283991 |
480 | 0.07792208 | 0.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
|
||||||
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
|
||||||
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 0 | 15.12 | 614400 | 0.000025 |
QoS 1 | 16.87 | 23938 | 0.000705 |
QoS 2 | 17.66 | 15489 | 0.001140 |
Wifi
QoS 0 | 2.02 | 368640 | 0.000005 |
QoS 1 | 0.93 | 26144 | 0.000036 |
QoS 2 | 0.89 | 13704 | 0.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
|
||||||
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
|
||||||
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 0 | 16.03 | 35446 | 0.000452 |
QoS 1 | 17.48 | 27510 | 0.000635 |
QoS 2 | 15.80 | 13552 | 0.001166 |
Wifi
QoS 0 | 0.59 | 64673 | 0.000009 |
QoS 1 | 0.70 | 32914 | 0.000021 |
QoS 2 | 0.86 | 17226 | 0.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
|
||||
1 second period |
Wifi – Connect & Wait
mW |
0
20
40
60
80
100
120
140
0
25
50
75
100
125
|
||||
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
相关推荐
Strategic information management system used to assist in investigations into serial crimes First commercial software created by Kim D....Analyzes crime locations to determine the most probable area of ...
通过指定以下项目设置,在任何sbt项目中添加scalac-profiling 。 addCompilerPlugin( " ch.epfl.scala " %% " scalac-profiling " % " 1.0.0 " ) 如何使用 要了解如何使用该插件,请阅读scala-lang博客中的。 ...
像这样标记您的代码: #[profiling::function]fn some_function () { burn_time ( 5 ); for i in 0 .. 5 { profiling :: scope! ( "Looped Operation" ); }} 请参见下面的结果可视化以及有关公开的API的更多详细...
traject_profiling 跟踪宏以提供有关MARC书目记录的配置文件信息。 该代码应与一起使用,以将MARC记录索引到。...to_field 'f700ind1' , field_ind_vals ( '700' , '1' ) # 700 ind1 values to_field 'f700ind2' ,
1. 安装与配置 Dynatrace Server:首先,确保你已经下载并安装了 Dynatrace Server。这通常涉及到在服务器上部署 dynatrace-server.jar 文件,并配置相应的环境变量,如 DYNATRACE_HOME 和 JAVA_OPTS。 2. 启动 ...
本文介绍了一种利用普通Wi-Fi设备进行精确的功率延迟分析的技术,具体来说,是通过商品化的Wi-Fi设备,即我们日常使用的无线网络设备,来进行精确的功率延迟剖面(Power Delay Profile, PDP)分析。功率延迟剖面是一...
1. **锁竞争频率**:如果一个锁被频繁争用,可能表示存在过多的同步操作或者锁粒度太细。 2. **等待时间**:线程等待获取锁的时间过长,可能表明锁的持有时间过长或者锁的公平性设置不当。 3. **锁持有时间**:如果...
剖析 这是关于在 Linux 上进行分析和一些示例文件。 目录结构: 幻灯片/来源 演示源 幻灯片/源/index.rst 幻灯片内容来源 幻灯片/构建/幻灯片 ...LICENSE_1_0.txt 升压许可证 README.rst 这个自述文件。
1. **XML和JSON解析**:FHIR资源通常以XML或JSON格式交换,因此需要熟悉.NET Framework或.NET Core中的XMLDocument、Json.NET等库来解析这些文件。 2. **FHIR模型理解**:理解和使用Hl7.Fhir.Model库,这是一个.NET...
1. **基准测试**:在初始状态下运行构建,记录基础时间。 2. **日志分析**:查看Travis CI的日志,找出耗时较长的步骤。 3. **优化尝试**:针对发现的问题,尝试优化,比如减少不必要的插件、提升模板渲染效率、优化...
监控和分析ClickHouse附加程序安装 node js(来自 .nvmrc 的版本)配置如有必要,更改配置文件: api -> .env 应用程序-> config.js发射光盘API npm ci npm 运行开发光盘应用程序npm ci npm 运行开发
gpu_memory_profiling 在pytorch代码中分析每一行的GPU内存使用情况用法示例python example_mnist.py相依性此代码取决于 。 点安装在这里可用: pip install py3nvml 使用pytorch版本0.4.0和py3nvml版本0.2.0进行了...
介绍项目的TA1原语当前,它为表格数据生成数据配置文件。 我们使用DataFrame(受支持)作为主要数据类型。要求请参阅安装首先安装项目。...numeric_char', 'number_of_numeric_values_equal_-1', 'most_comm
该项目致力于开源数据质量和数据准备解决方案。 数据质量包括策略定义的概要分析,过滤,治理,相似性检查,数据充实变更,实时警报,篮子分析,气泡图仓库验证,单个客户视图等。 该工具正在开发高性能的集成数据...
Geomajas 分析项目什么是 Geomajas Geomajas 是一个用 Java 编写的开源 Web 映射框架。 它提供服务器和客户端组件。 该项目包含 geomajas 分析项目。 有关该项目的更多详细信息、如何使用它、手册和其他信息,请查看...
TensorFlow分析套件的非官方Swift 该存储库包含成对的Python TensorFlow程序和Swift TensorFlow程序,以进行性能对比。 所有测试都将报告图形启动和图形完成之间的时间间隔。 注意:Swift中的计时器还将包含图形...1
Profiling探索了几种在 Java 中模拟货币金额的不同方法。 它还提供单元测试和基准测试来演示相关的 API:s 和输出分析结果; 最值得注意的是序列化和字节大小的时间成本。 JavaDoc 提供了 . 科技 - 构建工具。 - 单元...
DS Flow DS Flow是一个培训项目,允许通过vue.js spa应用程序分析数据集。 主要目标是通过开发过程学习vue.js框架。 除非您知道自己在做什么,否则请不要认真对待此代码。 它使用库进行数据集分析。...
Chapter 1: Getting Started with C++ on Android Chapter 2: Exploring the Android NDK Chapter 3: Communicating with Native Code using JNI Chapter 4: Auto-Generate JNI Code Using SWIG Chapter 5: Logging,...