c# - 有没有人有比较用 Xamarin C# 和 Java 编写的 Android 应用程序的性能的基准(代码和结果)?

标签 c# java android xamarin dot42

关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。












想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。

3年前关闭。



Improve this question




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

2013 年 6 月 18 日添加

由于没有答案并且找不到其他人完成的此类基准测试,因此决定进行自己的测试。不幸的是,我的问题仍然“锁定”,因此我无法将此作为答案发布,只能编辑问题。请投票重新打开这个问题。对于 C#,我使用了 Xamarin.Android 版本。 4.7.09001(测试版)。源代码,我用于测试和编译APK包的所有数据都在GitHub上:

java :https://github.com/gregko/TtsSetup_Java

C#:https://github.com/gregko/TtsSetup_C_sharp

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

我的测试结果

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

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

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

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

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

Java:总计时间(5 次运行):8947 毫秒,文件读取总计:9186 毫秒

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

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

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

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

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

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

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

模拟器 - 英特尔(Android 2.3.7,API 10)

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

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

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

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

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

简要讨论

我的测试代码主要包含文本解析、替换和正则表达式搜索,也许对于其他代码(例如更多数字运算),结果会有所不同。在配备 ARM 处理器的所有设备上,Java 的性能优于 Xamarin C# 代码。最大的区别是在 Android 2.3 下,其中 C# 代码运行速度约为Java 速度的 70%。

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

编辑 2013 年 7 月 8 日

我刚刚安装了 Genymotion Android 模拟器,它在 Oracle VirtualBox 中运行,并且这个模拟器再次使用原生 Intel 处理器,而不是模拟 ARM 处理器。与英特尔 HAX 仿真器一样,C# 再次在这里运行得更快。这是我的结果:

Genymotion 模拟器 - 英特尔(Android 4.1.1,API 16)

Java: Grand total time (5 runs): 2069 ms, with file reading total: 2248 ms

C#: Grand total time (5 runs): 1543 ms, with file reading total: 1642 ms



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

BN Nook XD+, ARM (Android 4.0)

Java: Grand total time (5 runs): 8103 ms, with file reading total: 8569 ms

C#: Grand total time (5 runs): 7951 ms, with file reading total: 8161 ms



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

三星 Galaxy Note 2 - ARM (Android 4.1.1)

Java: Grand total time (5 runs): 9675 ms, with file reading total: 10028 ms

C#: Grand total time (5 runs): 9911 ms, with file reading total: 10104 ms



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

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

Java: Grand total time (5 runs): 7153 ms, with file reading total: 7459 ms

C#: Grand total time (5 runs): 6906 ms, with file reading total: 7070 ms



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

编辑 2013 年 7 月 12 日

我们都知道,在速度方面,没有什么比本地代码更好的了,我对我的句子拆分器在 Java 或 C# 中的性能并不满意,特别是我需要改进它(从而使其更慢)。决定用 C++ 重写它。这是我的 Galaxy Note 2 上原生与 Java 速度的小型(即比以前的测试更小的文件集,出于其他原因)在禁用省电模式的情况下:

java :
总计时间(5 次运行):3292 毫秒,文件读取总计:3454 毫秒

原生拇指:
总计时间(5 次运行):537 毫秒,文件读取总计:657 毫秒

原生 ARM :
总计时间(5 次运行):458 毫秒,文件读取总计:587 毫秒

看起来对于我的特定测试, native 代码比 Java 快 6 到 7 倍。警告:无法在 Android 上使用 std::regex 类,因此必须编写自己的专门例程来搜索段落分隔符或 html 标签。我在 PC 上使用正则表达式对相同代码进行的初始测试比 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.RegularExpressions 类没有我在 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 total time (5 runs): 12187 ms, with file reading total: 13200 ms

Xamarin C#: Grand total time (5 runs): 13935 ms, with file reading total: 14465 ms

Dot42 C#: Grand total time (5 runs): 26000 ms, with file reading total: 27168 ms



三星 Galaxy Note 2,安卓 4.1.1 (ARM)

Java: Grand total time (5 runs): 6895 ms, with file reading total: 7275 ms

Xamarin C#: Grand total time (5 runs): 6466 ms, with file reading total: 6720 ms

Dot42 C#: Grand total time (5 runs): 11185 ms, with file reading total: 11843 ms



英特尔模拟器,Android 4.2 (x86)

Java: Grand total time (5 runs): 2389 ms, with file reading total: 2770 ms

Xamarin C#: Grand total time (5 runs): 1748 ms, with file reading total: 1933 ms

Dot42 C#: Grand total time (5 runs): 5150 ms, with file reading total: 5459 ms



对我来说,有趣的是,Xamarin C# 在较新的 ARM 设备上比 Java 略快,在旧的 Nexus One 上略慢。如果有人也想运行这些测试,请告诉我,我会更新 GitHub 上的源代码。看到带有英特尔处理器的真实 Android 设备的结果会特别有趣。

2013 年 7 月 26 日更新

只是一个快速更新,由具有最新 Xamarin.Android 4.8 和今天发布的 dot42 1.0.1.72 更新的基准应用程序重新编译 - 与之前报告的结果没有重大变化。

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

使用我的 Java 代码到 C# 的 Robert(来自 dot42 制造商)端口重新测试了 Dot42。在我最初为 Xamarin 完成的 C# 移植中,我用 C# 原生的 List 类替换了一些原生 Java 类,如 ListArray,等等。Robert 没有我的 Dot42 源代码,所以他再次从 Java 移植它并在这样的地方,有利于 Dot42,我猜是因为它在 Dalvik VM 中运行,如 Java,而不是在 Mono 中,如 Xamarin。现在 Dot42 的结果要好得多。这是我测试的日志:

7/30/2013 - Dot42 tests with more Java classes in Dot42 C#

Intel emulator, Android 4.2

Dot42, Greg's Code using StringBuilder.Replace() (as in Xamarin):
Grand total time (5 runs): 3646 ms, with file reading total: 3830 ms

Dot42, Greg's Code using String.Replace() (as in Java and Robert's code):
Grand total time (5 runs): 3027 ms, with file reading total: 3206 ms

Dot42, Robert's Code:
Grand total time (5 runs): 1781 ms, with file reading total: 1999 ms

Xamarin:
Grand total time (5 runs): 1373 ms, with file reading total: 1505 ms

Java:
Grand total time (5 runs): 1841 ms, with file reading total: 2044 ms

ARM, Samsung Galaxy Note 2, power saving off, Android 4.1.1

Dot42, Greg's Code using StringBuilder.Replace() (as in Xamarin):
Grand total time (5 runs): 10875 ms, with file reading total: 11280 ms

Dot42, Greg's Code using String.Replace() (as in Java and Robert's code):
Grand total time (5 runs): 9710 ms, with file reading total: 10097 ms

Dot42, Robert's Code:
Grand total time (5 runs): 6279 ms, with file reading total: 6622 ms

Xamarin:
Grand total time (5 runs): 6201 ms, with file reading total: 6476 ms

Java:
Grand total time (5 runs): 7141 ms, with file reading total: 7479 ms



我仍然认为Dot42还有很长的路要走。拥有类似 Java 的类(例如 ArrayList)并且它们具有良好的性能将使代码从 Java 移植到 C# 稍微容易一些。但是,这是我不太可能做很多事情的事情。我宁愿使用现有的 C# 代码(库等),这些代码将使用 native C# 类(例如 List),并且使用当前的 dot42 代码执行速度会很慢,而使用 Xamarin 会很好。

格雷格

最佳答案

是的,Xamarin 的 Mono 虚拟机比 Android 中使用的 Google 的 Dalvik 更令人印象深刻。我已经用 HTC Flyer 和 Acer Iconia Tab 平板电脑对其进行了测试,通过 Mono 对 Android 的 C# 端口与 Java Dalvik 进行了基准测试,Android 的 C# 实现很好,真正击败了基于 Java 的 Dalvik。

关于c# - 有没有人有比较用 Xamarin C# 和 Java 编写的 Android 应用程序的性能的基准(代码和结果)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17134522/

相关文章:

java - 如何从 Java 中的不同类读取私有(private)字段的值?

android - 使用客户经理 token 在 webview 中登录 Google 帐户

android - react native promise

C# 问题 : How do I save changes made in a DataGridView back to the DataTable used?

c# - 使用用户控件 C# 时的应用程序性能

java - 将列表作为参数传递给 JPQL 命名查询不起作用

java - 为 Eclipse 设置 Android 支持包 v7 - GridLayout

c# - NDepend 代码质量指标 - 自定义 CQL - 棕地开发

c# - 如何使用存储库模式将 EF 对象转换为 WCF 模型

java - 减少冗余的设计模式