在Qt上使用c++编写的Android设备应用程序比使用Android SDK使用Java编写的应用程序性能更好吗?
似乎所有其他的答案都是关于c++和Java的争论,所以我将尝试分享我在Android中关于Java和Qt编程的经验和知识。
首先,Android SDK是用Java实现的,因此开发者应该默认使用Java。.
更多的性能和更多的控制
但是在某些情况下需要更高的性能。游戏就是一个例子。图像处理是另一个用例。
在某些情况下,您需要使用c++来更好地控制硬件。(例如使用频率更高的加速度计)
也没有c++库来直接利用c++中的服务和操作系统特性(如联系人簿)。因此,您需要在使用c++的同时使用Java。为此,您需要在.java
文件中编写一些Java代码,并且需要使用JNI来通信c++和Java。JNI是您需要学习的另一个有问题的东西。
因此,使用c++开发Android应用程序比普通Java应用程序要困难得多。
.
我在Android上的Qt体验
我用QtQtQuick编写了一些Android应用程序,没有QtQuick控件。QtQuick对于UI开发来说是很棒的,但你需要做一些事情,比如手动管理加载和卸载UI。这不是问题,因为QtQuick中有一些用于此目的的功能,如Loader
。在桌面中实现应用程序的一般部分(非特定于Android部分)是非常高效、快速和有趣的(c++和QtQuick)。
但是在JNI中实现Android特定的部分需要更多的时间和精力。
.
Android上的Qt -利弊
- APK包很大(大多数情况下开销约为8mb)
- 需要发布多个APK包(ARM, x86) (Google play让你做得很好,没有最终用户通知)
- 应用启动时间高于正常应用
- 需要通过JNI 使用c++和Java结合开发调试困难<<li>更少的文档/gh>
- 及其快速UI
- 如果你打算在iOS等其他平台上发布应用,你只需要重新实现特定于操作系统的部分。这样你的时间/成本就会降低。
- 高性能后端处理和整体应用性能 更好的内存管理
- 在Android 2.2(例如)直到7.0质量相同!(Android SDK的一些功能只是在更高版本中,因此如果你打算支持较低版本的Android,你就不能使用这些功能。比如
AnimationFramework
。使用Qt你不会有这个问题) - 在早期Android版本和更高版本中使用HW加速UI
- 源代码保护
- 视图和模型/控制器的良好分离(有助于专业编码) 简单快速的UI开发简单而漂亮的UI效果(OpenGLES &(也自然集成到UI的其他组件)
.
建议如果(你不是Qt经验丰富的开发人员)=>使用Java
IF(你只需要一些处理的性能)=>Java + c++ (NDK)
如果(您是Qt经验丰富的开发人员)和((您是Java初学者)或(您计划将您的应用程序移植到其他平台))=>在c++中使用Qt
让我们将其分为两部分:
1) c++的性能会比Java好吗?
是的。当然会。它总是这样做的,只要您不向Java调用太多JNI。这就是为什么人们(包括Google)在性能最重要的地方使用c++。
2) QT是否比使用JNI返回Java或在NDK中使用c++可用的原始调用更好?
假设您以最佳方式编写这两种代码,顺序可能是原始NDK调用> Java调用> QT调用。QT库只是要做和你完全一样的函数调用,它只是在上面放了一个不同的抽象层。这一层会增加开销。大多数时候,开销可能是最小的。如果你是一个有经验的QT程序员,你可能会使用QT更快地编写代码,如果你是一个有经验的Android程序员,你会更快地完成它。QT会增加bug的几率,因为QT层本身的任何bug都会在你的代码中表现出来。
这个回答本来是作为评论的,但是它的长度很快就超过了限制。对不起:)
c++并没有神奇地比托管语言快。请忽略那些不这么认为的人。
c++所做的就是给你更多的旋钮来玩。如果您不是c++专家,那么在实际应用程序中,您可能会编写出非常不符合习惯的c++代码,其性能远不如简单的Java代码。给你两个具体的例子:初学者倾向于过度使用new
(默认情况下,它在c++中的性能很差),他们不明白什么时候隐式复制对象。
如果你投入了必要的时间来深入学习c++(1到10年),一个写得很好的c++程序可以比托管语言中的"对应程序"(如果存在的话)要快得多。
是的,有一些微小的基准测试证明c++比Java快n倍。如果你想要编写这样的基准测试程序,那么学习c++的一个子集是相对容易的。
编写一个微基准测试,显示std::list<T>
的性能比java.util.LinkedList<T>
差得多,这也是微不足道的。这是因为如果不为std::list<T>
节点提供专门的内存分配器,链表将把大部分时间花在内存分配上。这是否意味着c++比Java慢?不,它只是意味着,如果您想成为一名高效的c++程序员,分配器是您必须掌握的旋钮之一。Java程序员并不关心内存来自哪里,因为内存分配在Java中是不可定制的(无论好坏)。
以下是我通过C和Java对whitetstone和Linpack进行基准测试的结果。如果您为特定目标选择了错误的编译选项,编译的C代码可能会变慢,甚至与最佳选项[针对这些类型的CPU基准测试]非常相似。
After results是使用Java几乎与c相同的代码的示例。对于我的Android基准测试,所有使用相同的带有按钮和显示结果的Java前端。如果你需要更多的信息或程序(免费,没有广告)谷歌"罗伊安卓基准。
ARM v7-A15 rated 2000 MHz but running at 1700 MHz
Whetstone Benchmark
MWIPS ------MFLOPS------- ------------MOPS--------------
1 2 3 COS EXP FIXPT IF EQUAL
Java 533.9 131.4 209.4 102.5 20.4 6.7 475.8 174.8 105.7
C 1477.7 363.9 220.6 307.5 39.7 18.0 1690.5 2527.9 1127.9
Linpack Benchmark MFLOPS
Option C v5 C v7 C v7 C v7 Java
DP DP SP NEON SP DP
28.82 459.17 803.04 1334.90 143.06
Example function in C
startTime = getTime();
for (ix=0; ix<xtra; ix++)
{
for(i=0; i<n1*n1mult; i++)
{
e1[0] = (e1[0] + e1[1] + e1[2] - e1[3]) * t;
e1[1] = (e1[0] + e1[1] - e1[2] + e1[3]) * t;
e1[2] = (e1[0] - e1[1] + e1[2] + e1[3]) * t;
e1[3] = (-e1[0] + e1[1] + e1[2] + e1[3]) * t;
}
t = 1.0f - t;
}
t = t0;
endTime = getTime();
runTime = (endTime - startTime) / 1000.0;
Example function in Java
startTime = System.currentTimeMillis();
for (ix=0; ix<xtra; ix++)
{
for(i=0; i<n1*n1mult; i++)
{
e1[0] = (e1[0] + e1[1] + e1[2] - e1[3]) * t;
e1[1] = (e1[0] + e1[1] - e1[2] + e1[3]) * t;
e1[2] = (e1[0] - e1[1] + e1[2] + e1[3]) * t;
e1[3] = (-e1[0] + e1[1] + e1[2] + e1[3]) * t;
}
t = 1.0f - t;
}
t = t0;
endTime = System.currentTimeMillis();
runTime = (endTime - startTime) / 1000.0;