如何比较用Java和Xamarin c#编写的Android应用程序的性能?无论如何要检查定量数据(代码&结果)

我看到Xamarin声称他们在Android上的Mono实现和c#编译的应用程序比Java代码更快。有没有人在不同的Android平台上对非常相似的Java和c#代码执行实际的基准测试来验证这种说法,可以发布代码和结果?

2013年6月18日新增

因为没有答案,也找不到别人做的基准测试,所以我决定自己做测试。不幸的是,我的问题仍然“锁定”,所以我不能把这个作为答案,只能编辑问题。请投票重新讨论这个问题。对于c#,我使用Xamarin。Android Ver. 4.7.09001(测试版)。源代码,我用于测试和编译APK包的所有数据都在GitHub上:

Java: # EYZ0

c#: # EYZ0

如果有人想在其他设备或模拟器上重复我的测试,我也有兴趣了解结果。

我的测试结果

我将我的句子提取器类移植到c#(从我的@Voice Aloud Reader应用程序),并在英语、俄语、法语、波兰语和捷克语的10个HTML文件上运行了一些测试。每次运行对所有10个文件执行5次,3个不同设备和一个模拟器的总时间如下所示。我只测试了“发布”版本,没有启用调试。

HTC Nexus One Android 2.3.7 (API 10) - CyanogenMod ROM

Java: Grand总时间(5次运行):12361毫秒,文件读取总时间:13304毫秒

c#:总时间(5次运行):17504毫秒,文件读取总时间:17956毫秒

三星Galaxy S2 SGH-I777 (Android 4.0.4, API 15) - CyanogenMod ROM

Java: Grand总时间(5次运行):8947 ms,文件读取总时间:9186 ms

c#:总时间(5次运行):9884毫秒,文件读取总时间:10247毫秒

三星GT-N7100 (Android 4.1.1 JellyBean, API 16) -三星ROM

Java: Grand总时间(5次运行):9742毫秒,文件读取总时间:10111毫秒

c#:总时间(5次运行):10459毫秒,文件读取总时间:10696毫秒

模拟器-英特尔(Android 4.2, API 17)

Java:总时间(5次运行):2699毫秒,文件读取总时间:3127毫秒

c#:总时间(5次运行):2049毫秒,文件读取总时间:2182毫秒

模拟器- Intel (Android 2.3.7, API 10)

Java: Grand总时间(5次运行):2992毫秒,文件读取总时间:3591毫秒

c#:总时间(5次运行):2049毫秒,文件读取总时间:2257毫秒

模拟器- Arm (Android 4.0.4, API 15)

Java:总时间(5次运行):41751毫秒,文件读取总时间:43866毫秒

c#:总时间(5次运行):44136毫秒,文件读取总时间:45109毫秒

简短的讨论

我的测试代码主要包含文本解析、替换和Regex搜索,也许对于其他代码(例如更多的数值操作),结果会有所不同。在所有带有ARM处理器的设备上,Java的性能都优于Xamarin c#代码。最大的不同是在Android 2.3下,c#代码运行在大约。Java速度的70%。

在Intel模拟器上(使用Intel HAX技术,模拟器以快速virt模式运行),Xamarin c#代码运行我的示例代码要比Java快得多——大约快1.35倍。也许Mono虚拟机代码和库在Intel上比在ARM上优化得更好?

编辑2013年7月8日

我刚刚安装了Genymotion Android模拟器,它在Oracle VirtualBox中运行,同样,这个使用本机英特尔处理器,而不是模拟ARM处理器。与Intel HAX模拟器一样,c#在这里运行得更快。以下是我的结果:

Genymotion模拟器- Intel (Android 4.1.1, API 16)

< p > Java: 总时间(5次运行):2069 ms,文件读取总数:2248 ms

< p > C #: 总时间(5次运行):1543 ms,文件读取总数:1642 ms

然后我注意到Xamarin有更新。Android beta版本4.7.11,发布说明中提到了Mono运行时的一些变化。决定快速测试一些ARM设备,有一个大惊喜——c#数字提高了:

BN Nook XD+, ARM (Android 4.0)

Java: Grand总时间(5次运行):8103 ms,文件读取总时间:8569 ms

c#:总时间(5次运行):7951毫秒,文件读取总时间:8161毫秒

哇!c#现在比Java好?决定在我的Galaxy Note 2上重复测试:

三星Galaxy Note 2 - ARM (Android 4.1.1)

Java:总时间(5次运行):9675毫秒,文件读取总时间:10028毫秒

c#:总时间(5次运行):9911毫秒,文件读取总时间:10104毫秒

这里的c#似乎只是稍微慢了一点,但这些数字让我犹豫了一下:为什么Note 2的处理器更快,但运行时间却比Nook HD+要长?答案是:节电模式。在Nook上,它是禁用的,在Note 2上是启用的。决定在禁用省电模式的情况下测试(与启用省电模式一样,它也会限制处理器的速度):

三星Galaxy Note 2 - ARM (Android 4.1.1),省电禁用

Java: Grand总时间(5次运行):7153毫秒,文件读取总时间:7459毫秒

c#:总时间(5次运行):6906毫秒,文件读取总时间:7070毫秒

现在,令人惊讶的是,c#在ARM处理器上也比Java略快。大的改进!

编辑2013年7月12日

我们都知道,没有什么能比本机代码更快,我对我在Java或c#中的句子分配器的性能并不满意,特别是我需要改进它(从而使它更慢)。决定用c++重写。以下是我在Galaxy Note 2上禁用省电模式时本机和Java速度的一个小比较(由于其他原因,文件集比以前的测试要小):

< p > Java: 总时间(5次运行):3292 ms,文件读取总数:3454 ms

< p >本地经验法则: 总时间(5次运行):537 ms,文件读取总:657 ms

< p >本地的胳膊: 总时间(5次运行):458 ms,文件读取总:587 ms

看起来对于我的特定测试,本机代码比Java快6到7倍。警告:不能在Android上使用std::regex类,所以必须自己编写专门的例程来搜索段落中断或html标签。我最初在PC上使用regex测试相同的代码,比Java快4到5倍。

唷!用char*或wchar*指针再次唤醒原始内存,我立刻感觉自己年轻了20岁!:)

编辑2013年7月15日

(请参见下面,2013年7月30日的编辑,Dot42的更好的结果)

经过一些困难,我设法将我的c#测试移植到Dot42(版本1.0.1.71 beta),这是另一个用于Android的c#平台。初步结果显示,在英特尔Android模拟器上,Dot42代码比Xamarin c# (v. 4.7.11)慢大约3倍(3倍)。一个问题是Dot42中的system . text . regularexpresexpressions类没有我在Xamarin测试中使用的Split()函数,所以我使用了Java.Util.Regex类,而Java.Util.Regex. pattern .Split(),所以在代码中的这个特定位置,有这个小差异。不过应该不是什么大问题。Dot42编译为Dalvik (DEX)代码,因此它在Android上与Java原生合作,不需要像Xamarin那样从c#到Java的昂贵互操作。

为了比较,我也在ARM设备上运行测试——这里的Dot42代码“仅”比Xamarin c#慢2倍。以下是我的结果:

HTC Nexus One Android 2.3.7 (ARM)

Java: Grand总时间(5次运行):12187毫秒,文件读取总时间:13200毫秒

Xamarin c#:总时间(5次运行):13935毫秒,文件读取总时间:14465毫秒

Dot42 c#:总时间(5次运行):26000 ms,文件读取总时间:27168 ms

三星Galaxy Note 2, Android 4.1.1 (ARM)

Java: Grand总时间(5次运行):6895毫秒,文件读取总时间:7275毫秒

Xamarin c#:总时间(5次运行):6466毫秒,文件读取总时间:6720毫秒

Dot42 c#:总时间(5次运行):11185毫秒,文件读取总时间:11843毫秒

Intel模拟器,Android 4.2 (x86)

Java:总时间(5次运行):2389 ms,文件读取总时间:2770 ms

Xamarin c#:总时间(5次运行):1748毫秒,文件读取总时间:1933毫秒

Dot42 c#:总时间(5次运行):5150毫秒,文件读取总时间:5459毫秒

对我来说,同样有趣的是,Xamarin c#在新的ARM设备上比Java略快,而在旧的Nexus One上略慢。如果有人也想运行这些测试,请告诉我,我会在GitHub上更新源代码。如果能看到搭载英特尔处理器的真正Android设备的结果,那将是非常有趣的。

更新7/26/2013

只是一个快速更新,用最新的Xamarin重新编译了基准应用程序。Android 4.8,以及今天发布的dot42 1.0.1.72更新-与之前报告的结果相比没有显著变化。

2013年7月30日更新- dot42更好的结果

重新测试Dot42与罗伯特(从Dot42制造商)的端口我的Java代码到c#。在我最初为Xamarin所做的c#移植中,我用c#原生的List类替换了一些原生Java类,如lisstarray等。Robert没有我的Dot42源代码,所以他再次从Java移植,并在这些地方使用原始的Java类,这对Dot42有利,我猜是因为它运行在Dalvik VM中,像Java,而不是在Mono中,像Xamarin。现在Dot42的结果好多了。以下是我的测试日志:

2013年7月30日- Dot42在Dot42 c#中测试了更多Java类

英特尔模拟器,安卓4.2

Dot42, Greg's Code using StringBuilder.Replace() (as in Xamarin):
总时间(5次运行):3646 ms,文件读取总数:3830 ms

Dot42,格雷格的代码使用String.Replace()(在Java和罗伯特的代码):
总时间(5次运行):3027 ms,文件读取总数:3206 ms

Dot42,罗伯特的密码:
总时间(5次运行):1781 ms,文件读取总数:1999 ms

< p > Xamarin: < br > 总时间(5次运行):1373 ms,文件读取总数:1505 ms

< p > Java: < br > 总时间(5次运行):1841 ms,文件读取总数:2044 ms

ARM,三星Galaxy Note 2,省电关闭,安卓4.1.1

Dot42, Greg's Code using StringBuilder.Replace() (as in Xamarin):
总时间(5次运行):10875 ms,文件读取总数:11280 ms

Dot42,格雷格的代码使用String.Replace()(在Java和罗伯特的代码):
总时间(5次运行):9710 ms,文件读取总:10097 ms

Dot42,罗伯特的密码:
总时间(5次运行):6279 ms,文件读取总:6622 ms

< p > Xamarin: < br > 总时间(5次运行):6201 ms,文件读取总:6476 ms

< p > Java: < br > 总时间(5次运行):7141 ms,文件读取总数:7479 ms

我仍然认为Dot42还有很长的路要走。拥有类似Java的类(例如ArrayList)和良好的性能将使代码从Java移植到c#稍微容易一些。然而,这是我不太可能经常做的事情。我宁愿使用现有的c#代码(库等),这将使用本机c#类(例如List),这将与当前的dot42代码执行缓慢,与Xamarin非常好。

格雷格

56385 次浏览

是的,Xamarin的Mono虚拟机比谷歌在Android上使用的Dalvik更令人印象深刻。我已经在HTC Flyer和宏碁Iconia Tab平板电脑上进行了测试,通过Mono对Android的c#移植与Java Dalvik进行了基准测试,Android的c#实现很好地击败了基于Java的Dalvik。

我们最近在一款应用中使用了Xamarin。我们使用了之前为Windows RT版本应用编写的c#代码。为了Android版本,我们不得不重写了一些具体细节。

我们发现Xamarin c#中的I/O大约比Java慢2倍。我们的应用程序受到严重的I/O限制。我们还没有发现造成这种情况的原因,但目前我们假设这是由于编组。虽然我们大部分时间都在Mono VM中,但我们不知道Mono实际上是如何访问磁盘的。

这也说明我们的c#代码使用SQLite。净(# EYZ0)。使用SQLite进行相同的获取。NET代码也比使用Android的Java SQLite包装器慢2倍。在查看源代码后,它似乎直接绑定到C .dll,所以我不知道为什么它这么慢。一种可能是,在Android上从原生到Java的字符串封送比在Xamarin上从原生到c#的字符串更快。

# EYZ0。他将Xamarin与IOs和Android上的原生代码和Cordova进行了比较。

简而言之,Xamarin有时比本地代码执行得更好。他测试了应用程序的大小、加载时间、从Azure服务加载列表和质数计算。

享受吧!

编辑:我更新了死链接,我注意到有第二部分

I came across this interesting post

https://medium.com/@harrycheung/mobile-app-性能-redux-e512be94f976#.kfbauchtz

Android App Performance

iOS App Performance

希望这些信息能有所帮助。

https://github.com/EgorBo/Xamarin.Android-vs-Java是一个非常老的测试,但可能是相关的

算法测试

enter image description here

集合、泛型、自定义值类型

enter image description here

使用字符串

enter image description here

乌利希期刊指南:新数据与谷歌像素2(感谢yousha-aleayoub)

< a href = " https://camo.githubusercontent.com/76fd25443e2a407665389029ed594643b3f39f5f/68747470733a2f2f686162726173746f726167652e6f72672f776562742f65702f30642f76792f6570306476795f693878375f697a64733135383867796e716468772e706e67 " rel =“nofollow”noreferrer > < img src = " https://camo.githubusercontent.com/76fd25443e2a407665389029ed594643b3f39f5f/68747470733a2f2f686162726173746f726167652e6f72672f776562742f65702f30642f76792f6570306476795f693878375f697a64733135383867796e716468772e706e67 " alt = "像素2测试" > < / >

性能

如果不定义性能的含义,性能是一个模糊的词,如果只是简单的计算性能,Xamarin可以比Java快,这取决于计算的性质。

Android自带多种表单来执行代码:

  • RenderScript (CPU和GPU)
  • Java (SDK)
  • c++ (NDK)
  • OpenGL (GPU)

很明显,在执行代码时,解决方案越原生,速度就越快。基于运行时的语言永远不会胜过直接运行在CPU上的语言。

但另一方面,如果你想衡量现实生活中的使用性能,Java可能比Xamarin更快。

沙玛林以及它为什么会变慢

当将Xamarin与普通的旧Java应用程序进行比较时,Xamarin的性能可能会更快,因为它可能会更慢。

在一个真实的例子中,Xamarin应用程序很可能比Java应用程序慢,因为许多Android/Java(系统)调用需要使用所谓的绑定在Xamarin运行时之间进行委托。

有几种不同类型的绑定是很重要的:

  • 在许多android应用程序中使用的Java代码(SDK)和原生c++代码(NDK)之间的接口绑定。
  • 一个在Xamarin中可用的绑定,用于从托管的c#代码到Java代码(Android运行时)的接口。
  • 一个在Xamarin中可用的绑定,用于从Java代码(Android运行时)到托管c#代码的接口。

更多关于MCW和ACW的信息:https://developer.xamarin.com/guides/cross-platform/application_fundamentals/building_cross_platform_applications/part_1_-_understanding_the_xamarin_mobile_platform/

绑定在性能方面是非常昂贵的。从Java调用c++方法会增加大量的调用时间开销,而从c++内部调用c++方法要快很多很多倍。

有人做了一个性能测试来计算JNI调用平均花费多少Java操作:进行JNI调用的定量开销是什么?

但是不仅仅是JNI的调用是昂贵的,从MCW和ACW的调用也是。现实世界中的Xamarin应用程序使用绑定进行许多调用,因此现实世界中Xamarin应用程序的使用可能(而且通常会)比普通的旧Java应用程序慢。然而,根据Xamarin应用程序的设计方式,用户很可能甚至不会注意到这种差异。

TLDR /结论: Xamarin需要使用艾尔排序绑定,这是耗时的。

除了绑定,在讨论实际性能时还涉及到许多其他因素,例如:二进制文件的大小,在内存中加载应用程序,I/O操作等等。一篇调查这些事情的博客文章可以在这里找到:https://magenic.com/thinking/mobile-development-platform-performance-part-2-native-cordova-classic-xamarin-xamarin-forms

以下是我在native, Xamarin和Xamarin之间的另一个测试中发现的一些信息。在以下两个设备上形成解决方案(测试还包括iOS性能):

< p > # EYZ0: Android操作系统版本:6.0 中央处理器:八核1.9 GHz Cortex-A53 内存:3 gb 显示分辨率:1920×1080

< p > # EYZ0: iOS版本:10.3.3 中央处理器:双核1.84 GHz Twister 内存:2gb 显示分辨率:1334×750

比较了一些共同的特点,每一个都有自己的应用:

- Basic “Hello World”
- REST API
- JSON Serialization/Deserialization
- Photo Loading
- SQL Database Insert and Get All

每个测试重复几次,图表显示了平均结果。


你好世界

Basic Hellow World performance comparison


Rest API

一组测试,旨在测量应用程序通过REST API发送请求并在不进行进一步数据处理的情况下,使用OpenWeatherMap API接收响应所需的时间。

Rest API性能比较


< >强JSON操作 使用Newtonsoft Json.net框架对所有Xamarin应用程序中的JSON对象进行序列化和反序列化测试。 本机Android序列化和反序列化使用两个Java库进行测试:Jackson和GSON

执行了两次运行,第一次从头开始,第二次使用缓存的信息和操作

第一次运行:

JSON serialization first run

JSON反序列化first run

(顺便说一下,原生iOS JSON Operations正在杀死这个测试,Xamarin在第二个测试中加入了它)

JSON Serialization second run

JSON反序列化第二次运行


图片操作

首先加载三种不同分辨率的图像:

Resolution – 858×569, Size – 868Kb
Resolution – 2575×1709, Size – 8Mb
Resolution – 4291×2848, Size – 28.9Mb

Image First Load Android

Image First Load iOS

关于沙玛林似乎有些不确定。生成此测试的结果,因此不包括在图中。


SQLite操作

测试了两个操作:

BulkInsert: Loading rows of data into a database table.
GetAll: Retrieving all data from the database.

数据库有10,000条记录。所有操作都在设备内部进行。

SQLite Android性能

SQLite iOS性能


Xamarin Native (Xamarin. ios /Xamarin. android)显示自己是原生代码的很好的替代品,而Xamarin。表单在很多情况下似乎很慢,但对于快速开发非常简单的应用程序来说,它是一个非常好的解决方案。

完整的测试来自此来源:

https://www.altexsoft.com/blog/engineering/performance-comparison-xamarin-forms-xamarin-ios-xamarin-android-vs-android-and-ios-native-applications/

谢谢你给我的解释来加强我的回答,希望这有一点帮助:)