Writing Native Android Code: NDK vs. RenderScript
While efficient, correct coding goes a long way towards making Android applications smooth and highly responsive, some applications can benefit from running code outside the boundaries of Android's Java VM, known as the Dalvik VM. These apps instead run their code natively.
The Android platform provides two methods for operating outside the traditional Android application boundaries. The first and most widely available method is to use the Native Development Kit (NDK). The second method is to use RenderScript (RS), a low-level, high-performance programming language. Both mechanisms can be useful for 3D rendering and CPU-intensive computations.
In this article, we compare the NDK and RS to help you decide when to use one over the other.
NDK vs. RenderScript: Programming Languages and Portability
The NDK allows developers to write code in C or C++ and interface with their Android applications through the Java Native Interface (JNI) mechanism. The libraries available are standard, and existing C/C++ code can often be ported with few changes. Also, C++ is not that different from Java and many developers are well versed in both languages.
RenderScript takes a different approach, using C99 syntax (standard C from 1999, the current standard is C11, from 2011) with new APIs that are ultimately compiled to native code. While this syntax is well known, there's a learning curve to using this system because the APIs are not.
The ultimate in portability is to have libraries that work across the broadest range of devices and platforms. The NDK lets you leverage your existing C/C++ libraries, which you may already be using on other platforms. RenderScript is not portable from other C apps, however it's more widely available across Android devices than the NDK. For example, RenderScript works on Google TV devices, but there is currently no NDK support available for the Google TV platform, even though it runs Android.
NDK vs. RenderScript: Compilation and Debugging
Code written with the NDK must be compiled for each target native platform ahead of time. If the app is launched on a platform with an unsupported architecture, the NDK portions of the application will not function properly. RenderScript does a first pass compile on your development machine and then a final pass on the target device, resulting in more efficient native binary code. This means that any device that supports RenderScript will run your code, regardless of the architecture.
Currently, RenderScript results in code that runs only on the main CPU, and automatically generates code that can leverage multiple cores when they are available on the target device. However, in the future, there are plans have it run on the GPU as well. This is similar to the CUDA or OpenCL platforms.
Applications that leverage the NDK can be line-level debugged using gdb. RenderScript, on the other hand, can't be debugged while it's running. Given the nature of RenderScript and how it works with multiple cores, this isn't a huge surprise, but this can make finding and eliminating bugs more difficult.
NDK vs. RenderScript: Performance
Neither the NDK nor RenderScript provides a magic bullet for performance. Both increase project complexity, reduce portability, increase testing requirements, complicate debugging, and increase the maintenance burden on the project. If your project doesn't require a lot of computation, leverages only the basic graphic capabilities of OpenGL, or runs fast enough already, neither the NDK nor RenderScript are likely to benefit your project enough to bother with.
For pure computational uses, RenderScript setup and configuration is easy and the results may in fact outperform similar implementations that use the NDK, with less coding necessary. RenderScript is best used for 3D user interfaces or high-performance computational tasks. The NDK on the other hand is better suited for high-performance OpenGL apps or games that need access to more features of the graphics SDK or access to third-party libraries.
Simple OpenGL tasks or computations that aren't CPU bound in Java are best left alone. Performance improvements are always being made to the Java compiler and the Dalvik VM. Leaving your code alone in Java will allow your applications to take advantage of these performance improvements and run better on future SDK versions or devices.
RenderScript code may improve in the future as the final compile step improves and more hardware support and compute support are added for GPUs. Native code through the NDK, on the other hand, is unlikely to see performance improvements other than those that come about through hardware changes. Consequently, NDK code benefits the most from highly efficient algorithms and coding.
Ultimately, the choice to use the NDK, RenderScript , or stay within the realm of Java is entirely up to you, the developer. It's an application design decision with considerable ramifications -- it effects what programming language you're using, what devices your application can run on, and how complicated your source project is from a maintenance perspective.
You have read a variety of the pros and cons of both the NDK and RenderScript. They are not necessarily interchangeable, but similar solutions can be achieved with both technologies in many instances. Understanding how both NDK and RenderScript can work for you will help you make a better decision on which to use on a given project. Either way, there are tools available to help you make your application run as fast as possible on as many devices as possible.