I'm wondering about performance and cpu/ram requirements for 2 different methods of starting runnables
I have some code that collects sensor data every 10ms and inserts the values into a database on a background thread (using a single thread executor). Executor service is created as follows:
executor = Executors.newSingleThreadExecutor();
One way to do that would be something like...
public void onSensorChanged(SensorEvent event) {
//get sensor values
//insert into database
executor.execute(new Runnable(){
//database insert code here
});
}
I see this method a lot in tutorials, but because I'm doing this every 10ms, it feels resource intensive as I'm creating a new object every single time a sensor value change is detected. Does this new object just get overridden every 10ms? Or is it taking up increasing amounts of RAM as new objects are created?
I have since refactored my code to look more like this:
executor = Executors.newSingleThreadExecutor();
myRunnable = new MyRunnable();
class MyRunnable implements Runnable {
public void run() {
//database insert code here
}
}
public void onSensorChanged(SensorEvent event) {
//get sensor values
//insert into database
executor.execute(myRunnable);
}
My thinking is that I instantiate only a single object once, instead of doing it every time sensors change. Am I correct in thinking this has lower RAM usage than the previous method? Is there a more efficient/better way to accomplish this task?
executor.execute()
is adding tasks to a queue, where each queued task is doing the save? – ScissileRunnable
. In second example you cannot, becauseevent
is not visible inMyRunnable
. So you will need some another intermediate object whereSensorEvent
objects (or derivative) are stored prior save to DB. I suggested queue as the most common pattern for producer-consumer task. – DegreedayAsyncTask
which is already provided by the Android. In the example that you are using the same instance of the runnable , i suppose that you are passing some details in it before commiting to the executorService queue. What will happen in case that you have a secondonSensorChanged()
call , but the previous one havent finished yet ? if you make the fields volatile , it wont be async , and if you dont , you will lose some calls – ObcordateonSensorChanged
I collect the sensor values as an array and replace that initial float array. So that array gets overwritten every 10ms with the latest values. TheMyRunnable
class then just gets the values of that array and inserts into the database – Scissileexecutor.execute()
just add things to a queue? So even if a second set of sensor data comes in, it will just sit in the queue behind the first set and it'll all get processed in the order of arrival. Thats what I'm hoping happens anyway, otherwise you're right, I'll lose some data – Scissile