Home > OS >  What is the most efficient way to pass data between method invocations except using parameters in Ja
What is the most efficient way to pass data between method invocations except using parameters in Ja

Time:02-21

I'm instrumenting a Android project for a specific testing purpose. I hope to transfer some information (e.g., an infoObj object) between method invocations. So the basic idea is to use a map (indexed by thread id to avoid concurrency issues) to store the infoObj before invoking a method, and then retrieve the infoObj from the map at the beginning of the invoked method body.

For example, here are two methods f1 and f2 where f1 invokes f2.

void f1() {
  f2();
}

void f2() {
}

After instrumenting, they become:

void f1() {
  map.put(threadID, infoObj); // put infoObj into the map before invoking f2
  f2();
}

void f2() {
  map.remove(threadID); // get infoObj from the map at the beginning of f2
}

It works well in most of the cases. But when method invocations occur in a long loop, the instrumented program runs much slower than its original one. Using parameters to transfer is the best solution but unfortunately I cannot modify method definitions because program semantics may change.

What is the most efficient solution to achieve my goal?

CodePudding user response:

There isn't really a good way of doing this in Java. The main problem is that if you have multiple threads you need a map and maps are moderately expensive to use due to them having to calculate hashes and locate the item in the internal data structures.

Note that HashMap is also not thread-safe. You haven't said whether you have made it safe (e.g., using Collections.synchronizedMap). If you have, then you are better using ConcurrentHashMap which is much faster than a synchronized HashMap. If you haven't, making it thread-safe will only get worse.

I can suggest a few things:

  1. You might be able to avoid the issue by predicting which thread you are in. I am not an expert on Android, but quite often certain bits of code can only be in certain threads and there might not be a lot of multi-threading going on unless you initiated it yourself. If that is the case you can just create a specific static for that code-point and reference it directly.
  2. If you can't avoid using maps, you could scour the internet for faster map implementations.
  3. Can you do the put operation elsewhere? Writing to a map is the slowest part, so if you can pre-populate it for the thread, that might speed things up. You also don't want to be allocating memory (calling new) in your instrumentation code, so make sure infoObj is pre-allocated and re-use it on each call.
  • Related