8 votes

Le NDK Android permet-il d'accélérer l'envoi de gros int[] sur des sockets ?

J'ai besoin d'envoyer un tableau de 500 000 ints sur un socket entre deux appareils Android. Pour l'instant, je passe beaucoup de temps à convertir les int[] en byte[] pour que le socket de Java les accepte (voir ma question précédente). Envoyer efficacement de grands int[] sur des sockets en Java où nous avons déterminé qu'il n'y a pas de moyen plus rapide de faire le typecasting en Java).

Ma question est la suivante : si je prends l'int[] et que je le passe par JNI au NDK Android, puis-je espérer que la conversion en byte[] soit plus rapide dans le code natif ? Je sais que le typage de int* en char* est assez simple dans le bon vieux C, mais je me demande si la JNI n'annulera pas tout gain de performance.

En outre, une fois que j'ai un byte[] dans mon code natif, puis-je le renvoyer efficacement à mon code Java ou dois-je implémenter le socket en C également ?

Edit 1 : Les gens ont posté beaucoup de réponses sans cliquer sur le lien. L'utilisation de ByteBuffers n'est pas une bonne option En fait, il est beaucoup plus lent que mask-and-shift, qui est toujours beaucoup plus lent que mon code critique de performance a besoin ! C'est pourquoi je pose des questions sur le NDK.

Edit 2 : J'ai modifié le texte ci-dessus pour dire que le code C peut passer de int* à char* au lieu de int[] à byte[]. J'espère que cela clarifie la question.

Edit 3 : Pour clarifier mon cas d'utilisation, il s'agit d'un problème de recherche où je distribue un grand tableau d'ints sur plusieurs périphériques et je trie la liste en parallèle. Supposons que j'ai 500 000 ints en Java (peu importe d'où ils viennent) et que j'ai besoin de les faire sortir du périphérique via un socket aussi rapidement que possible. Les réponses qui disent "ne commencez pas avec un tableau d'ints" ne sont pas utiles. En outre, le code de mon application doit être aussi proche que possible de 100 % de Java. Si le typage natif et les sockets améliorent les performances, c'est bien, mais je ne peux rien faire d'autre (c'est-à-dire le tri) en natif.

2voto

Samuel Points 5878

Non, l'utilisation de JNI/NDK ne vous permettra pas d'améliorer les performances. Tout d'abord, lorsque vous essayez de transférer le tableau dans le code natif, vous devez le copier ou utiliser un ByteBuffer directement alloué. . Il s'avère que l'implémentation de Dalvik VM renvoie toujours le pointeur direct de Get*ArrayElements(). Je doute que vous obteniez une amélioration des performances car les appels via JNI ont un coût supplémentaire. Enfin, le C++ et Java ont des performances très proches dans ce scénario (cf. Performances du C++ par rapport à Java/C# ).

Jetez un coup d'œil à cette question et à la première réponse pour trouver un moyen rapide de convertir un int[] en un byte[] en Java. Comment convertir un int[] en byte[] ?

Y a-t-il une raison pour laquelle vous utilisez un int[] au lieu d'un byte[] pour commencer ? S'il s'agit d'une image, nous pourrions vous recommander des moyens d'éviter la conversion.

1voto

oldrinb Points 10991

Utilisez un SocketChannel et vous pouvez utiliser ByteBuffer à la place.

buffer.asIntBuffer().put(ints);
do {
  channel.write(buffer);
} while (buffer.hasRemaining());

1voto

Alex Cohn Points 13248

Si le code Java a besoin d'un accès efficace à int[] alors il y a de fortes chances que l'envoi/réception en natif avec des sockets en vaille la peine.

Mais il est souvent possible d'utiliser IntBuffer au lieu de int[]. Dans ce cas, vous pouvez allouer un ByteBuffer et en extraire un IntBuffer :

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

Vous devriez expérimenter à la fois allocate() et allocateDirect(), voir " ByteBuffer.allocate() vs. ByteBuffer.allocateDirect() " et http://objectissues.blogspot.co.il/2005/10/java-nio-allocate-vs-allocatedirect.html .

Important ! Dans ce cas, vous obtiendrez UnsupportedOperationException si vous essayez d'utiliser ib.array() .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X