I doubt if there is a way to make compile-time conditions in Java like #ifdef #ifndef in C++.
My problem is that have an algorithm written in Java, and I have different running time improves to that algorithm. So I want to measure how much time I save when each improve is used.
Right now I have a set of boolean variables that are used to decide during the running time which improve should be used and which not. But even testing those variables influences the total running time.
So I want to find out a way to decide during the compilation time which parts of the program should be compiled and used.
Does someone knows a way to do it in Java. Or maybe someone knows that there is no such way (it also would be useful).
private static final boolean enableFast = false;
// ...
if (enableFast) {
// This is removed at compile time
}
Conditionals like that shown above are evaluated at compile time. If instead you use this
private static final boolean enableFast = "true".equals(System.getProperty("fast"));
Then any conditions dependent on enableFast will be evaluated by the JIT compiler. The overhead for this is negligible.
javac will not output compiled code that is unreachable. Use a final variable set to a constant value for your #define and a normal if statement for the #ifdef.
You can use javap to prove that the unreachable code isn't included in the output class file. For example, consider the following code:
public class Test
{
private static final boolean debug = false;
public static void main(String[] args)
{
if (debug)
{
System.out.println("debug was enabled");
}
else
{
System.out.println("debug was not enabled");
}
}
}
javap -c Test gives the following output, indicating that only one of the two paths was compiled in (and the if statement wasn't):
public static void main(java.lang.String[]);
Code:
0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3; //String debug was not enabled
5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
I think that I've found the solution, It's much simpler.
If I define the boolean variables with "final" modifier Java compiler itself solves the problem. Because it knows in advance what would be the result of testing this condition.
For example this code:
boolean flag1 = true;
boolean flag2 = false;
int j=0;
for(int i=0;i<1000000000;i++){
if(flag1)
if(flag2)
j++;
else
j++;
else
if(flag2)
j++;
else
j++;
}
runs about 3 seconds on my computer.
And this one
final boolean flag1 = true;
final boolean flag2 = false;
int j=0;
for(int i=0;i<1000000000;i++){
if(flag1)
if(flag2)
j++;
else
j++;
else
if(flag2)
j++;
else
j++;
}
runs about 1 second. The same time this code takes
int j=0;
for(int i=0;i<1000000000;i++){
j++;
}
Never used it, but this exists
JCPP is a complete, compliant,
standalone, pure Java implementation
of the C preprocessor. It is intended
to be of use to people writing C-style
compilers in Java using tools like
sablecc, antlr, JLex, CUP and so
forth. This project has has been used
to successfully preprocess much of the
source code of the GNU C library. As
of version 1.2.5, it can also
preprocess the Apple Objective C
library.
http://www.anarres.org/projects/jcpp/
If you really need conditional compilation and you use Ant, you might be able to filter your code and do a search-and-replace in it.
For example: http://weblogs.java.net/blog/schaefa/archive/2005/01/how_to_do_condi.html
In the same manner you can, for example, write a filter to replace LOG.debug(...); with /*LOG.debug(...);*/. This would still execute faster than if (LOG.isDebugEnabled()) { ... } stuff, not to mention being more concise at the same time.
If you use Maven, there is a similar feature described here.
If you use IntelliJ there is a plugin called Manifold, that - along with many other features - allows one to use #ifdef and #define in Java.
Plugin url:
https://manifold.systems/
Preprocessor information:
https://github.com/manifold-systems/manifold/tree/master/manifold-deps-parent/manifold-preprocessor
PS: I am not affiliated with them, we just happen to use it, and it helps a lot with out workflow (which is likely NOT typical for Java development)
Use the Factory Pattern to switch between implementations of a class?
The object creation time can't be a concern now could it? When averaged over a long running time period, the biggest component of time spent should be in the main algorithm now wouldn't it?
Strictly speaking, you don't really need a preprocessor to do what you seek to achieve. There are most probably other ways of meeting your requirement than the one I have proposed of course.
final static int appFlags = context.getApplicationInfo().flags;
final static boolean isDebug = (appFlags & ApplicationInfo.FLAG_DEBUGGABLE) != 0
Related
I created an app. I want my one app only per mobile but i can create clone of my app using Parallel Spaceļ¼Multi Accounts. So my question is how to stop to making clone of my app. Is android have any unique identifier, which is not alterable even if user reset the phone?
I think there is not a way to prevent "Parallel Space" to clone your app, that is something related with android system.
A simple workaround I use is to check whether the Parallel Space app is installed(ps package name: com.lbe.parallel.intl).
public boolean isAppInstalled(String packageName) {
try {
getPackageManager().getApplicationInfo(packageName, 0);
return true;
}
catch (PackageManager.NameNotFoundException e) {
return false;
}
}
As you can guess it is not reliable since many different apps can be used for this purpose. I didn't go further for my case but one thing that comes to my mind; if you have file write permission you can create a global file and put something there to check while opening your app.
Someone who knows how such apps work can provide better answers. If they are changing something in your apk while copying, then you can check those changes or hashcode of the apk, but it seems that they run your app in a virtual os, so this may not lead to a solution.
And there is not a successful unique id on android unfortunately. That is something I hate about android. I check different identifiers like deviceid, imei, mac address etc.. but parallel space creates new values for all of them.
After I searched a lot for a solution to stop the app cloning, I came across this idea, which is to check the path in which the app data is installed on the phone.
The following code explains the idea further:
int APP_PACKAGE_COUNT = 2; //----> my app package name is com.test.app the number is count of dots in package name
private void checkClonner() {
String path = this.getFilesDir().getAbsolutePath();
int count = getDotCount(path);
if (count > APP_PACKAGE_COUNT) {
throw new RuntimeException("This app does not work in a cloning environment");
}
}
private int getDotCount(String path) {
int count = 0;
for (int i = 0; i < path.length(); i++) {
if (count > APP_PACKAGE_COUNT) {
break;
}
if (path.charAt(i) == '.') {
count++;
}
}
return count;
}
A work collegue has implemented a class to load native C++ shared libraries into our Android app, he named this class 'LibLoader'. His proposed solution was to instantiate a LibLoader object every time we needed to use one of the native functions declared in the native library. I believe this is not optimum from a performance point of view so I was thinking about the best way to optimize this.
So far two solutions have come into my mind:
Make the LibLoader class a singleton
Turn the native methods into static ones so I won't even have to make an object
Considering native shared libraries are loaded through static/instace initializacion in the class, my questions are:
Which of these two approaches would be the best from a performance point of view? I need my code to be fast, I'm calling these native functions several times to compute FFTs on real time audio samples
Is there another optimum way to do this?
What happens to static/instance initialization if the native methods are converted to static ones? Will it be called every time a static method is accessed?
My code is:
public class LibLoader {
static final String TAG = "LibLoader";
static boolean armv7 ;
static
{
String arch = System.getProperty("os.arch");
//determine which library to load according to CPU type
if(arch.contentEquals("armv7l"))
{
//fftw neon compiled library functions work with armv71 and armv6
try {
System.loadLibrary("fftwfNeon_fftTwiddle"); //this won't load from any other platform
armv7 = true;
}catch (UnsatisfiedLinkError e)
{
Log.e(TAG, "Unable to load fftwfNeon_fftTwiddle library "+ e.getMessage());
}
}
else
{
try {
System.loadLibrary("fftTwiddle");
armv7 = false;
}catch (UnsatisfiedLinkError e)
{
Log.e(TAG, "Unable to load fftTwiddle library "+ e.getMessage());
}
}
}
public native void GetComplexFFtDoubleIN(double[] realIN, double[] imagIN, int fftSize, double[] TW, boolean ifftFlag);
public native void FFTWfNeonSymb(int fftSize, float[] realPart, float[] imagPart, boolean isFFT);
public native void FFTWfNeonSync(int fftSize, float[] realPart, float[] imagPart, boolean isFFT);
}
Having your methods static vs creating an instance variable for the class, does not affect CPU performance much. But these 2 implementations differs a lot in memory usage.
If it is only FFT calculations then, I would suggest to keep it static. This can keep you code free from memory leaks.
Update: Creating a singleton is between the 2 options I have explained. Here are the 3 ways you can do it in the order of memory simplicity.
All methods are static and you directly access the methods from any class you want. (Only has the class in memory)
Having a singleton variable. Creating a new variable will always return the same static variable. (Keeps the class and the static variable in memory)
Creating a new variable and deleting the memory after using the required methods in the class. (Allocates memory when needed and clears it when not in use.)
I am developing a C++ game on Android NDK (android-ndk-r9b). If I write this:
class Test
{
char c[1024*1024*1024];
};
//in main
try {
Test* p;
while (1) {
p = new Test();
}
} catch (bad_alloc) {
cout << "bad_alloc\n";
}
it doesn't throw. If I try this:
void no_memory_by_new() {
cout << "no_memory_by_new\n";
throw bad_alloc();
}
//in main
set_new_handler(no_memory_by_new);
Test* p;
while (1) {
p = new Test();
}
it doesn't work either. Finally, if I try this:
//in main
set_new_handler(no_memory_by_new);
int* p;
while (1) {
p = new int[1024*1024*1024];
}
then no_memory_by_new is called. I'm really confused about this. Can anyone help me?
This is bug in Android build of GNU libstdc++. If you look into operator new implementation, you'll see it call _GLIBCXX_THROW_OR_ABORT if malloc return NULL. Next, if you look on definition of _GLIBCXX_THROW_OR_ABORT, you'll see it throw bad_alloc only if __EXCEPTIONS defined; otherwise, it just call abort. For some reason, __EXCEPTIONS macro is not defined in Android build of GNU libstdc++, so it call abort - exactly what you see in your case.
I've checked this behaviour with both Android NDK r10d and CrystaX NDK 10.1 - and it's the same in both cases. I've filed ticket to fix this in CrystaX NDK. For fixing that in Google's NDK, you should also file ticket in Google's NDK bug tracker
UPD: It seems that situation is not so simple... Investigating it further, I've found more details pointing to the fact there is something bit more complicated than I've described above. Looking further; will update answer when have strict results.
UPD2: After deep investigation I've found that my previous answer was completely wrong. In fact, __EXCEPTIONS are defined when building GNU libstdc++, so operator new actually throw bad_alloc if malloc return NULL. The problem is in your code actually, but it was bit tricky to figure out. See explanation below.
TL;DR: operator new return pointer to the "allocated" memory (so from its point of view, there's no reason to throw std::bad_alloc), but first access to that memory cause crash because actually those pages are not available.
More detailed explanation:
Here is complete code I've used for testing:
#include <new>
#include <stdio.h>
#include <string.h>
class Test
{
public:
Test() {
::fprintf(stderr, "ctor start\n");
//memset(c, 0, sizeof(c));
::fprintf(stderr, "ctor finish\n");
}
private:
char c[1024*1024*1024];
};
int main()
{
try {
while (1) {
Test *p = new Test();
if (!p)
return 1;
}
return 1;
} catch (std::bad_alloc) {
return 0;
}
}
If you compile this test and run it on device, you'll get std::bad_alloc on some iteration (I get it on third iteration). But if you uncomment memset in constructor of Test, application will crash on the first memset call. If you remove constructor of Test completely, it will crash too - just because in this case compiler will generate constructor, which do zero-initialization of all members - i.e. the same as we do with memset.
The difference here is that malloc (used internally in operator new) returns pointer to the "allocated" memory, but actually it is not allocated; this region is just marked as "need to be allocated in future, when application will actually refer it". This is how Linux kernel handle it, for performance reasons. On next step, when you (or compiler) fill array with zeros, application actually access those pages but, unfortunately, there's just no free memory in system, so Linux kernel call OOM killer, killing the process as result.
This is not Android-specific. In fact, the same happens on GNU/Linux systems; the only difference is amount of memory available to the system (on Android it much lower than on servers, for obvious reasons).
In order to have working exceptions, you need to build using one of the other C++ standard libraries, other than the default one. Add e.g. APP_STL := gnustl_static to jni/Application.mk. Additionally, you need to enable exceptions, add LOCAL_CPP_FEATURES += exceptions to your Android.mk, or add APP_CPPFLAGS += -fexceptions to jni/Application.mk.
I am trying to set the TCP Keep Alive Socket option and adjust some of its value using the NDK, at this point, I think the NDK version is irrelevant.
The relevant code is C++, is called from a method in a class and looks like the following:
// Assume the socket handle is valid and was created with socket()
// Enable TCP Keep Alive
int nOptVal = 1;
setsockopt(hSocket, SOL_SOCKET, SO_KEEPALIVE, reinterpret_cast<char*>(&nOptVal), sizeof(nOptVal));
// Every 15 secs.
nOptVal = 15;
setsockopt(hSocket, SOL_TCP, SO_KEEPINTVL, reinterpret_cast<char*>(&nOptVal), sizeof(nOptVal));
// Send a single probe
nOptVal = 1;
setsockopt(hSocket, SOL_TCP, SO_KEEPCNT, reinterpret_cast<char*>(&nOptVal), sizeof(nOptVal));
When I try to compile the above, the SO_KEEPINTVL and SO_KEEPCNT macros are unfound and I cannot seem to find their definition in the include files of the NDK.
As anyone ever made this work?
One last note, I cannot do it from the java code since the options need to be set on sockets that are inside a library the java code is using.
I looked through SO and found this question which explains how to do it in Java so it should be possible, I guess.
Thanks for any help on this.
To sum up, correct macro names are TCP_KEEPINTVL and TCP_KEEPCNT. They are defined in the linux/tcp.h file.
I'm trying to figure out the difference between accessing android string resources. The following quote is not clear to me:
Access by referene is fast
Direct access is slow
access by reference means: setTitle(R.string.title)
direct access means: setTitle(getResources().getString(R.string.title))
Now I've run some speed tests on the android emulator:
access by reference:
for(int i = 0; i< 100000; i++) {
setTitle(R.string.app_name);
}
This took 5090 milliseconds. In contrast I run the same code, using direct access:
for(int i = 0; i< 100000; i++) {
setTitle(getResources().getString(R.string.app_name));
}
This took 5191 milliseconds. I tested this with Android 4.2.2.
So for me it looks a lot like it doesn't matter which way I use the resources. Did this matter in earlier android versions? Does this matter on real devices? In other words: Does it matter which access I choose?
If more parameters of my testing are needed, I'm happy to give them. Thank you for taking the time, appreciate it a lot.
Just look at the code :
(in Activity)
public void setTitle(int titleId) {
setTitle(getText(titleId));
}
(in Context)
public final CharSequence getText(int resId) {
return getResources().getText(resId);
}
So basically, it is exactly the same thing.
What is much slower, however, is if you use Resource.getIdentifier(String, String, String) to find the ids of your resources.