This is probably an easy one. I have about 20 TextViews/ImageViews in my current project that I access like this:
((TextView)multiLayout.findViewById(R.id.GameBoard_Multi_Answer1_Text)).setText("");
//or
((ImageView)multiLayout.findViewById(R.id.GameBoard_Multi_Answer1_Right)).setVisibility(View.INVISIBLE);
My question is this, am I better off, from a performance standpoint, just assigning these object variables? Further, am I losing some performance to the constant "search" process that goes on as a part of the findViewById(...) method? (i.e. Does findsViewById(...) use some sort of hashtable/hashmap for look-ups or does it implement an iterative search over the view hierarchy?)
At present, my program never uses more than 2.5MB of RAM, so will assigning 20 or so more object variables drastically affect this? I don't think so, but I figured I'd ask.
Thanks.
Yes, this would be correct to cache references to the views. That's what the ListView's Tag/Holder is about which is there for performance reasons.
Related
I'm writing android using couchdb. I have around 1000 documents. Every DB operation invokes a view,my view is taking a lot of time. Is there a way to optimize views in couch db? If there are less documents then fetching documents is working fast.
The main things to note with views are that both map and reduce values are cached in the view index (see http://horicky.blogspot.co.uk/2008/10/couchdb-implementation.html for details), that views are only rebuilt when you look at them, and that the CouchDB JavaScript engine is not particularly fast.
There's a few options to use all this for actual performance improvements:
Accept stale data in your views, and periodically rebuild the view index asynchronously. You can query views with ?stale=ok to immediately return the currently cached view index, from the last time the view was built, and then have some other background task querying with stale != ok to actually do the rebuild. The typical strategies for this are either to rebuild the view every X minutes or watch /db/_changes rebuild the view after every Y changes. Depends on your application.
Accept stale data and then always immediately rebuild the view asynchronously afterwards. This uses ?stale=update_after, which I believe will immediately return you a value and then do the view rebuild in the background. Whether to do this or the above depends on your use case and how important up to date values are to you; this might end up with your rebuilding the view far more than is really necessary, and thereby actually slowing down your queries. This does seem easier than the previous option though.
Push as much of your code into your map function as possible. This should improve performance in quickly changing databases, because map values are cached and don't need updating until the underlying document changes, whereas reduces need recalculating whenever one of a larger set of documents changes. I'm not sure exactly how reduce recalculation is tuned in CouchDB, i.e. how big the set that needs recalculating is, but it's definitely going to happen more the map recalculations, and potentially much much more.
Use built-in reduce functions (see http://wiki.apache.org/couchdb/Built-In_Reduce_Functions) instead of rewriting them in JavaScript. These fulfil many standard reduce cases, and are much much faster than writing the equivalent function yourself.
Rewrite your map/reduce in Erlang. See http://wiki.apache.org/couchdb/EnableErlangViews. This does require you to learn Erlang, but should just take away big percentage of your view rebuilding time.
The map function in a view is executed only once per document (plus as many times as you update the document). This happens at the first time you query the view. After that the result of the map function does not have to be computed anymore and therefore the query to the view should be extremely fast. As views are already efficient there is no general way to optimize them further.
This is not the case for temporary views. If you are using these, please store them in a design document to turn them into regular views.
Emit the smallest amount of data as possible in your document in the map function. You can access the entire document using the include_docs=true url parameter if you actually need the entire document
Good
{
map: function(doc) {
emit(doc._id, null)
}
}
Bad
{
map: function(doc) {
emit(doc._id, doc)
}
}
If I have a view that I will be referencing with decent regularity (to change its visibility, etc...), is it more efficient to store this View as a member variable or to execute findViewById() each time I need a reference to it?
The member variable requires memory usage, while the method my take more time. Is anyone aware of an established best practice for this?
It is much more efficient to store the reference. The memory cost of the reference will be minimal (I don't remember the exact cost but it's in the order of 4 bytes.)
The real concern is where you store the reference. Above all else, you don't want to be holding the reference when the View is no longer in use; Bad Things can result if you do.
I am facing the problem of low memory. Low memory:no more background process And here is the scenario.
I am using a list which gets its data from a string array, it has a custom background, Clicking on item, the list gets another string array to display as second or third level. Information for three levels written in database.
After third level, there are two more levels for which data is going to be fetched from web services,
And that causes the low memory error.
How can I get rid of the solution?
Edit : After having some digging I found that the GC is trying to (kill or) restart in case of its already crashed com.android.inputmethod.latin/.latinIMEservice. One notable point is that the application is translated in french and italian, but this screen does not have any text for translation, does this information helps??
Edit 2: After a detailed study of traceview I found that all the text views have custom fonts applied in it. (There is a call of TypeFace.createFromAsset()) that IMO causes the crashes.
And the problem lies in the fact that I have to keep the fonts....
can It be possible to avoid crash and have the fonts?? (Because i think the answer is no: But still waiting for some opinions)
Edit 3 : After removing the custom fonts the performance of application is much better. Hence I can suspect the font is the only culprit here. And that's why I am editing question. The font I use is helvetica.
Can using external fonts cause application to crash or running out of memory? If yes can you describe the cause in more detail??
Thanks
If you are using code similar to:
Typeface font = Typeface.createFromAsset(getContext().getAssets(),
"fonts/Helvetica.ttf");
try making "font" a global variable so it only gets loaded once. Otherwise it can be loaded repeatedly, quickly consuming memory. See this message for a little more detail
Well, question is a bit unclear to have answered:
After each level - do you switch/start to another Activity? If so you shouldn't keep anywhere references to old activity. Otherwise it could trigger OOM problems
I suppose you're fetching data using some kind of Cursor alike object. Cursor's are very memory-consuming objects, so you'd better not only just close Cursor's, but you should also call Cursor.deactivate()
I know rule #1 of optimization is: don't do it! But I figured this was an easy question, and if I start using the faster method now I can save a lot of cpu time when I'm finished.
I'm making an RPG, and let's say this is part of a custom class:
public class Baddie{
int health;
int magic;
public Baddie(int health, int magic){
this.health = health;
this.magic = magic;
}
public int getHealth(){
return health;
}
Now, the answer to my question may be "there's no difference" and that's fine with me.. I just want to know. Is it quicker to get the Baddie's health using field access:
//Somewhere in the main thread, I get an instance of Baddie..
Baddie b = getScaryBadGuy();
int baddieHealth = b.health;
Or is it quicker to use a return method?
int baddieHealth = b.getHealth();
Copied and pasted from Designing for Performance:
Avoid Internal Getters/Setters
In native languages like C++ it's
common practice to use getters (e.g. i
= getCount()) instead of accessing the field directly (i = mCount). This is
an excellent habit for C++, because
the compiler can usually inline the
access, and if you need to restrict or
debug field access you can add the
code at any time.
On Android, this is a bad idea.
Virtual method calls are expensive,
much more so than instance field
lookups. It's reasonable to follow
common object-oriented programming
practices and have getters and setters
in the public interface, but within a
class you should always access fields
directly.
Without a JIT, direct field access is
about 3x faster than invoking a
trivial getter. With the JIT (where
direct field access is as cheap as
accessing a local), direct field
access is about 7x faster than
invoking a trivial getter. This is
true in Froyo, but will improve in the
future when the JIT inlines getter
methods.
Performance is always relative. It's usually better to think in terms of percentages or factors. If something takes a microsecond, maybe that's a lot, and maybe it's nothing. It depends on how many times per second you need to do it. That's the main reason premature optimization is frowned upon, it is done without knowing if there is a problem.
The compiler will optimize if it can. This is a perfect example of premature optimization. use whatever makes sense in your code. Don't worry about "saving cycles". The 2-3 cycles this may or may not save is outweighed by the millions of cycles it takes for any other operation.
IMO it's more a design question than optimization question. I would suggest not writing/generating any getter or setter until you actually need them to be accessed from outside of your class. This tends to keep coupling as low as possible.
Alternatively making those getters/setters private by default would have the same result but it's more code for no real benefit.
Just a random question. I'm learning a bit of Android right now, and in most examples, it seems a lot of common items (such as buttons, editboxes etc) get requested within each function using (cast) findViewById().
Is it considered good or bad practice to store the result of that in an Activity's member values? Simple example:
public class MyActivity extends Activity {
private EditText myText;
public void onCreate(blah blah) {
// blah
this.myText = (EditText) findViewById(R.id.mytext);
}
}
and use the myText field from there on. I think it'd be good for performance (depending on findViewById's inner workings, I'm quite sure it's already very fast), but I haven't seen it be encouraged yet. Also, it wouldn't be the first time I encountered a situation where 'caching' something like this leads to problems (had a case where database connections weren't released properly because I remembered a ConnectionManager or something in that fashion).
Secondly, somewhat related, if you want to remember something across methods in your Activity (and later on too, when the Activity is restarted later), is it wiser to keep up both a class field and a value in SharedPreferences, or would calling SharedPreferences each time for setting / getting the value where it's needing be a better solution? (better being 'cleaner, without impacting performance significantly)
That is completely normal practice and is exactly what you SHOULD be doing. If you're worried about memory leaks, or holding references or whatever, don't be concerned about that when dealing with views.
However, you SHOULD be careful about holding references to other contexts because that COULD cause a memory leak. That doesn't mean you shouldn't do it, just be careful about when you're doing it.
is it wiser to keep up both a class field and a value in SharedPreferences, or would calling SharedPreferences each time for setting / getting the value where it's needing be a better solution?
You should do both. You should keep a member variable for when you only need to read the data, just be sure that when you WRITE to the member variable, you also change the shared preference.
Also, it wouldn't be the first time I encountered a situation where 'caching' something like this leads to problems (had a case where database connections weren't released properly because I remembered a ConnectionManager or something in that fashion).
This is what I was saying first. It all depends on what you're storing. Views are fine to store, contexts can be dangerous, and database connections and registered listeners can cause really weird bugs. It all depends on the specific case.