【发布时间】:2012-09-05 21:46:00
【问题描述】:
我需要通过两个 Android 设备之间的套接字发送一个包含 500,000 个整数的数组。目前,我花费大量时间将 int[] 转换为 byte[] 以便 Java 的套接字能够接受它(请参阅我之前的问题 Efficiently send large int[] over sockets in Java,我们确定在 Java 中没有更快的类型转换方法) .
我现在的问题是,如果我采用 int[] 并通过 JNI 将其传递给 Android NDK,我能否期望在本机代码中对 byte[] 进行类型转换更快?我知道在普通的 C 中将 int* 类型转换为 char* 非常简单,但是我想知道 JNI 是否会否定任何性能提升。
此外,一旦我的本机代码中有一个 byte[],我可以有效地将它传递回我的 Java 代码,还是我也需要在 C 中实现套接字?
编辑 1:人们在没有点击链接的情况下发布了很多答案。 使用 ByteBuffers 不是一个好的选择,它实际上比 mask-and-shift 慢得多,这仍然比我的性能关键代码需要慢得多!这就是我询问 NDK 的原因。
编辑 2:我将上面的文字更改为 C 代码可以从 int* 转换为 char* 而不是 int[] 转换为 byte[]。希望这能澄清问题。
编辑 3:为了澄清我的用例,这是一个研究问题,我在多个设备上分布大量整数数组并对列表进行并行排序。假设我在 Java 中有 500,000 个整数(不管它们来自哪里),我需要尽快通过套接字将它们从设备中取出。说“不要以整数数组开头”的答案没有帮助。此外,我的应用程序代码需要尽可能接近 100% Java。如果本机类型转换和套接字提高了性能,那没关系,但我不能在本机做任何其他事情(即排序)。
【问题讨论】:
-
int[]不能“类型转换”为byte[].. 在任何情况下,可以使用buffers 还是必须是byte[]? -
@pst 不会将
int[]解释为 C 中 4x 长度的工作(忽略字节序等)的(unsigned char *)?在 Java 中通过套接字发送int[]的要点是,您(或缓冲区)需要在某个时候将其转换为byte[],这比 arraycopy 工作量更大,而 C 应该能够做到这一点(获取 int[ ] 来自 java 并以本机代码发送)无需转换,因为它可以以不同的方式解释相同的数据。 -
@zapl 我不使用 JNI。但是,这似乎有点粗略,并且依赖于实现细节..无论如何,这仍然会导致 C
char*而不是 Javabyte[]。我不知道 JNI 是否允许对内存中的数组进行一些神奇的包装,尤其是 已经属于另一个对象的内存 .. 需要一种方法来告诉 JNI“分离”@ 987654332@ 来自为其分配的内存,因为它现在属于新的假设byte[]对象。此外,这种对(char*)的强制转换在C 中似乎是有问题的。例如,考虑字节序。 -
@pst 是的,不回到 Java
byte[](其中 int[] 和 byte[] 使用相同的内存是不可能的)。以不需要手动转换的方式直接发送某些 Java 对象(或该对象的内存副本 - 了解 JNI 如何处理该对象)正在使用的数据。不是一种(类型/字节序/..)安全方式,而是一种提高通过套接字以任何方式发送 Java int[] 的潜在性能的方式。 -
@pst 我不担心从 int[] 到 char* 的转换的字节序,因为我也控制接收套接字(我可以在那里修复字节序)。任何能够加快传输端的解决方案都会有所帮助。
标签: java android performance casting android-ndk