除了在 Java 中使用参数之外,在方法调用之间传递数据的最有效方法是什么?
我正在为一个特定的测试目的检测一个 Android 项目。我希望在方法调用之间传输一些信息(例如,infoObj 对象)。因此基本思想是在调用方法之前使用映射(通过线程 id 索引以避免并发问题)存储 infoObj
,然后从映射中检索 infoObj
在被调用方法体的开头。
例如,这里有两个方法 f1
和 f2
,其中 f1
调用 f2
。
void f1() {
f2();
}
void f2() {
}
检测后,它们会变成:
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
}
在大多数情况下效果很好。但是,当方法调用发生在长循环中时,检测后的程序的运行速度会比原始程序慢得多。使用参数来传输是最好的解决方案,但不幸的是我无法修改方法定义,因为程序语义可能会改变。
实现我的目标最有效的解决方案是什么?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在 Java 中确实没有一个好的方法来做到这一点。主要问题是,如果您有多个线程,则需要一个映射,并且映射的使用成本相当昂贵,因为它们必须计算哈希值并在内部数据结构中定位项目。
请注意,
HashMap
也不是线程安全的。您还没有说明是否已确保其安全(例如,使用Collections.synchronizedMap
)。如果有,那么最好使用 ConcurrentHashMap,它比同步的 HashMap 快得多。如果没有,使其成为线程安全只会让它变得更慢。顺便说一句,
ThreadLocal
有其自己的内部自定义映射实现。我想这是为了性能而做的,而且它一定比使用 HashMap 更快(否则为什么要麻烦呢?)。因此,为什么你会看到它变慢是一个谜,除非你没有同步,这可能会解释它。我可以建议一些事情:
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., usingCollections.synchronizedMap
). If you have, then you are better usingConcurrentHashMap
which is much faster than a synchronizedHashMap
. If you haven't, making it thread-safe will only make it slower.Incidentally,
ThreadLocal
has its own internal custom map implementation. I would imagine this is done for performance and that it must be faster than using HashMap (else why bother?). So why you are seeing it as slower is a puzzle, unless you are not synchronizing, which might explain it.I can suggest a few things: