8

2 つの Android デバイス間のソケットを介して 500,000 int の配列を送信する必要があります。現在、私は int[] を byte[] に変換して、Java のソケットがそれを受け入れるようにするのに多くの時間を費やしています (以前の質問Efficiently send large int[] over sockets in Java を参照してください。より高速な方法はないと判断しました)。 Java で型キャストを行うため)。

私の質問は、int[] を取得して JNI を介して Android NDK に渡すと、ネイティブ コードで byte[] への型キャストがより高速になることを期待できますか? int* から char* への型キャストは、昔ながらの C では非常に簡単であることは知っていますが、JNI がパフォーマンスの向上を無効にするかどうか疑問に思っています。

さらに、ネイティブ コードで byte[] を取得したら、それを効率的に Java コードに戻すことができますか、それとも C でもソケットを実装する必要がありますか?

編集 1: 人々はリンクをクリックせずに多くの回答を投稿しています。ByteBuffers を使用するのは適切なオプションではありません。実際には、マスク アンド シフトよりもはるかに遅く、パフォーマンスが重要なコードのニーズよりもはるかに遅いです。そのため、NDK について質問しています。

編集 2: 上記のテキストを変更して、C コードは int[] から byte[] ではなく int* から char* にキャストできると述べました。うまくいけば、それは質問を明確にします。

編集 3: 私のユースケースを明確にするために、これは int の大きな配列を複数のデバイスに分散させ、リストを並行してソートするという研究上の問題です。Java に 500,000 個の int があり (どこから来たかは関係ありません)、できるだけ早くソケットを介してデバイスから取り出す必要があるとします。「int の配列から始めないでください」という回答は役に立ちません。さらに、私のアプリケーション コードは、可能な限り 100% Java に近づける必要があります。ネイティブの型キャストとソケットがパフォーマンスを改善する場合、それは問題ありませんが、他のこと (つまり、並べ替え) をネイティブで行うことはできません。

4

3 に答える 3

2

いいえ、JNI/NDK を使用してもパフォーマンスは向上しません。まず、配列をネイティブ コードに渡そうとするときは、それをコピーするか、直接割り当てられた ByteBuffer を使用する必要があります。Dalvik VM の実装は、常に Get*ArrayElements() から直接ポインターを返すことが判明しました。JNI を介した呼び出しにはオーバーヘッド コストがかかるため、パフォーマンスが向上するとは思えません。最後に、このシナリオでは C++ と Java のパフォーマンスが非常に似ています ( C++ のパフォーマンスと Java/C#を参照)。

Java から int[] を byte[] に変換する高速な方法については、この質問と最初の回答をご覧ください。int[] を byte[] に変換する方法

そもそも byte[] の代わりに int[] を使用している理由はありますか? 画像の場合は、変換を回避する方法を推奨できる場合があります。

于 2012-09-12T20:14:14.483 に答える
1

a を使用すると、代わりに sSocketChannelを使用できます。ByteBuffer

buffer.asIntBuffer().put(ints);
do {
  channel.write(buffer);
} while (buffer.hasRemaining());
于 2012-09-12T20:20:24.097 に答える
1

Java コードが への効率的なアクセスを必要とする場合、int[]ソケットを使用したネイティブの送受信が有効である可能性が高くなります。

しかし、多くの場合、int[] の代わりに IntBuffer を使用しても問題ありません。この場合、ByteBuffer を割り当てて、そこから IntBuffer を取得できます。

ByteBuffer bb = ByteBuffer.allocate(500000*4);
IntBuffer ib = bb.asIntBuffer();

allocate() と allocateDirect() の両方を試す必要があります。 -vs-allocatedirect.html .

重要!この場合、UnsupportedOperationExceptionを使用しようとすると が得られますib.array()

于 2012-09-13T10:49:41.170 に答える