I'm an old school developer (OK, I'm 20, I'm not old school, I just like printing it out instead of using the step-by-step debugger :P ) and I have a lot of Log.i() calls in an Android application. I was wondering if it would have an impact on the performance of the app?
I know I should use a step-by-step debugger, it's just that debugging multiple threads can be a little cumbersome.
Thanks for your help!
I don't think Log will affect to application performance, because when release app, you turn off it in Android Manifest by setting debuggable:
<application android:icon="#drawable/icon"
android:label="#string/app_name"
android:debuggable="false">
I'm still looking into Android coding myself but I from what I've seen so far I would assume that the Android logging suffers from the same issues that most Java logging frameworks suffer from (The notable exception being SLF4J), namely:
Logging does effect performance because:
It means extra method calls. (Not an issue for 99% of apps).
It often means String assembly work (Big impact)
It engages extra IO (Big impact)
Developers typically deal with this by adding guard blocks
if (log.isDebugEnabled()) {
log.debug("...");
}
I think the Android SDK can do this as well. it covers off #2 and #3, but still leaves your release code containing unused logging code. assuming of course that you never want to enable debug logging in a release situation.
SFL4J BTW, doesn't require guard blocks because it used C like method calls which delay String assembly until it's actually required. Unfortunately it appears that Android has not gone down this path. iOS doesn't have this problem either because it has a pre-compiler. Something that I often wish Java had kept.
Anyway, I would not advocate removing logging in favour of the debugger. IMHO they server two different purposes. Logging I find very useful (if done properly) in understanding the flow of an application. I've often found problems by looking through logs that I would not have found in the debugger. Ie. unnecessary code execution across multiple classes (especially in UI classes), odd data issues that don't lead to actually bugs, etc. In these situations using the debugger would be like trying to lay concrete with a spoon. Debuggers on the other hand are perfect for analysing the fine details of an issue highlighted by the logging.
So in my code I tend to have a fair amount of logging which is designed to tell me what the application is doing, in an English like manner so I can read it easily and understand what is happening. But I'm fairly strict about keeping the levels as low as possible. Ie. don't log stuff at the info level unless it's something you want to see even in release mode. I've found a lot of developers tend to break this.
UPDATE: Just read Remove all debug logging calls before publishing: are there tools to do this? which talks about how you can use ProGuard to strip logging from release code. Great idea, means you can not bother with guard blocks on logging and put as much in as you like, yet still be assured that your release code will be fast.
If you switch to Log.d, then you can debug your application, and when building a release version, none of those calls will be compiled or executed.
Yes, it does have performance penalty. check this: Log.d and impact on performance
The answer is yes and no.
It depends on how many Log calls you have and as you're talking about step-debugging, I'm guessing you're not worried about release code at this stage (when you'd obviously remove excessive logging).
I've used excessive logging to the point it overflows the logcat but only when trying to track down a particularly elusive problem in my debug code - that logging was removed as soon as I tracked the problem down.
In short, log as much as you like in development but don't inflict it on the user.
Related
My customer raise a problem about our app which is the app is getting slower when using for long time, but our side cannot simulate the problem as we are not in their real working environment, we are not able to solve the problem before knowing the bug. anyone can help?
If it´s a issue that raises "by the passing of time", you should look for any task you might be running and repeating itself.
You should check the different types of functionalities you use.
For example, if your app it´s using a local database:
Look for unclosed cursors.
I/O work
If your are using animations:
Look for skipped frames
Complex view hierarchies
If using background tasks or threading:
I/O work
Unfinished threads
Increasing thread number
If using networking and Webservices:
Problems with your server database
Connection issues
Proxys
...
You could also use something like Firebase + Crashlytics to see if theres any warning raises but gets silently disposed.
Giving some more info about your app and what it does could be useful for elaborating more accurate solution.
A common source of slowing down apps is memory leaks.
on iOS what you can do is to activate Memory management flags on your target and keep a watch on the logs, you can also use Xcode Memory Graph and instruments leak tools to detect leaks.
on Android you can use tools like LeakCanary to be notified when leaks happens.
Once you have a leak detected you can inspect your code to identify the source and better manage memory.
#axierjhtjz mention lots of good starting points.
Does it occur on both iOS and Android, specific devices, vendors?
If it is mainly on a single platform (Android/iOS), on different devices and the main complaint is slowness over time, I would suspect the following:
Memory leak (maybe UI, fragments)
Data persistent data incremental over time or/and more IO operation over time.
If you unable to debug the problem on the customer site, I would suggest to add a remote real time monitoring capabilities over relevant parameters and logs.
A good tool we used in the past was TestFairy. maybe they have a free trial
My question is simple. If I make an app with android studio leaving in print functions, will they run when I run the app and take up computational power? or will android studio automatically get rid of them? Or do they stay there but not run due to a lack of a console to print to?
Basically: Do I need to get rid of print functions in android studio in order to have my app running at its highest performance capabilities?
Thank you very much.
Edit:
I should mention that I am using a library that prints numerous diagnostic pieces of information, and it would be a bit of a project in itself to try to remove the System.out.print functions from this library. This is why I am asking specifically about print functions.
Yes you should get rid of print statements otherwise they will affect performance. A better solution to this is to use Timber library by Jake Wharton. This library takes care of removing log statements for release builds automatically. Also this library has some pretty good APIs to improve logging workflows.
well you should Make sure you deactivate logging and disable the debugging option before you build your application for release.
For me, logging is far too important to remove from the source, but it must be removed from the production application, for performance, secure and intellectual property reasons.
System.out.print
It is same as Log like Log.e() or Log.i() or Log.d()
When you have this logcats in your final APK then when it runs it will prints that statements in the Android Moniter and this will be helpfull to know what is happening in the app.
A coworker and I were talking (after a fashion) about an article I read (HTC permission security risk). Basically, the argument came down to whether or not it was possible to log every action that an application was doing. Then someone (an abstract theroetical person) would go through and see if the app was doing what it was supposed to do and not trying to be all malicious like.
I have been programming in Android for a year now, and as far as I know if -- if -- that was possible, you would have to hack Dalvik and output what each process was doing. Even if you were to do that, I think it would be completely indecipherable because of the sheer amount of stuff each process was doing.
Can I get some input one way or the other? Is it completely impractical to even attempt to log what a foriegn application is doing?
I have been programming in Android for a year now, and as far as I know if -- if -- that was possible, you would have to hack Dalvik and output what each process was doing.
Not so much "hack Dalvik" but "hack the android.* class library, and perhaps a few other things (e.g., java.net).
Even if you were to do that, I think it would be completely indecipherable because of the sheer amount of stuff each process was doing.
You might be able to do some fancy pattern matching or something on the output -- given that you have determined patterns of inappropriate actions. Of course, there is also the small matter of having to manually test the app (to generate the output).
Is it completely impractical to even attempt to log what a foriegn application is doing?
From an SDK app? I damn well hope so.
From a device running a modded firmware with the aforementioned changes? I'd say it is impractical unless you have a fairly decent-sized development team, at which point it is merely expensive.
This is both possible and practical if you are compiling your own ROM. Android is based on Linux and I know several projects like this for Linux, like Linux Trace Toolkit. I also know of research into visualizing the results and detecting malicious apps from the results as well.
Another thing functionality like this is often used for is performance and reliability monitoring. You can read about the DTRACE functionality in Solaris to learn more about how this sort of stuff is used in business rather than academia.
Is there a way to somehow intercept calls to the standard Log in android and perform some other action?
In desktop Java one would usually get some logger so there are ways to install a different logging handler / implementation. However, Android seems to have a static call to Log, and I could not find any information about replacing the default behavior.
I realize I can monitor the device log through ADB, but I'd like to have a different behavior in running apps on a device who opt in (e.g., by executing a certain instruction when the program starts out).
As AedonEtLIRA points out Log is final so you need to roll/borrow a new one. I've been using Prasanta Paul's "MLog": http://prasanta-paul.blogspot.com/2010/07/custom-logger-for-android.html
It makes it easy to save logs to a text file and/or disable logging completely.
If it doesn't already do what you need, it is a good base for managing logging.
I think your best solution would be to replace all the Log calls in your application with your own class, MyLog, then call Log if they don't opt-in, and call your special logging feature if they opt-in.
Replacing all the Log calls shouldn't be hard, just a find and replace.
In addition to MLog proposed by #Darrell, there are several other logging frameworks for Android, including:
logback-android
log4j-android
microlog4android
Of the three, logback (the next-gen log4j) seems to be the most capable and have the richest API (and lots of documentation), while microlog is the most compact (but limited in features...but maybe it does all you need). All three support the SLF4J logging facade, so you can easily swap out microlog for logback, log4j, jul, or some newer framework down the road.
As with MLog, these frameworks require replacing the calls to android.os.util.Log (it doesn't "intercept" the calls as you might be after).
Because Log is final, I think you will have to write your own logging system and implement that if you want to change anything.
From what I've seen and read, if someone really wants to reverse-engineer your software or decompile it, ProGuard is not going to stop them. But is it at least a modest deterrent? I'm not sure if it's worth the hassle of translating my stack traces later on.
I would recommend ProGuard. Even without obfuscation (which can significantly shorten the names used in the constant pool) it can remove "dead code" (unused methods) of used libraries, etc. (It can also be used to conveniently merge everything together).
It takes a little bit of fiddling to "get correct", esp. if there is dynamically loaded classes -- but very recommended. The actual benefit from space-saving, however, "depends" on what can be eliminated and generally goes up with more external libraries.
Now, for obfuscation -- it does as much as any obfuscator: Makes "decompiling" code into things with meaningful names impossible.
Obfuscation won't save your super-secret-algorithm or hide your private keys, though: if the JVM (or Dalvik after a transformation) must understand it, then so can a decompiler and anyone who really wants to get access can. Your code could even be lifted in bytecode-form and used simply via. reflection (just imagine a terrible API with zero documentation): anyone who really wants to get access can. But perhaps obfuscation will make this task unfeasible for the cost/payout: "It depends".
Don't want to translate stack-traces? Simple: don't use it for debugging (not as useful for getting traces from users) or don't enable obfuscation (other benefits still apply) ;-)
Happy coding.
Pro guard is at least enabling you to have the app become as small as possible regarding the filesize!
That's a real plus.
It's automatically used when developing and compiling with eclipse, provided if you have proguard.config=proguard.cfg to the project's default.properties file.
That's also a real plus.