Flu*_*dan 22 java performance foreach loops premature-optimization
我有这样的事情:
Map<String, String> myMap = ...;
for(String key : myMap.keySet()) {
System.out.println(key);
System.out.println(myMap.get(key));
}
Run Code Online (Sandbox Code Playgroud)
所以myMap.keySet()
在foreach循环中调用一次?我想是的,但想要你的意见.
我想知道如果以这种方式使用foreach(myMap.keySet()
)会对性能产生影响,或者它等同于:
Set<String> keySet = myMap.keySet();
for (String key : keySet) {
...
}
Run Code Online (Sandbox Code Playgroud)
Edd*_*die 65
如果你想绝对肯定,那么两种方式编译并反编译并进行比较.我用以下来源做到了这一点:
public void test() {
Map<String, String> myMap = new HashMap<String, String>();
for (String key : myMap.keySet()) {
System.out.println(key);
System.out.println(myMap.get(key));
}
Set<String> keySet = myMap.keySet();
for (String key : keySet) {
System.out.println(key);
System.out.println(myMap.get(key));
}
}
Run Code Online (Sandbox Code Playgroud)
当我用Jad反编译类文件时,我得到:
public void test()
{
Map myMap = new HashMap();
String key;
for(Iterator iterator = myMap.keySet().iterator(); iterator.hasNext(); System.out.println((String)myMap.get(key)))
{
key = (String)iterator.next();
System.out.println(key);
}
Set keySet = myMap.keySet();
String key;
for(Iterator iterator1 = keySet.iterator(); iterator1.hasNext(); System.out.println((String)myMap.get(key)))
{
key = (String)iterator1.next();
System.out.println(key);
}
}
Run Code Online (Sandbox Code Playgroud)
所以有你的答案.它以for-loop形式调用一次.
Val*_*her 35
它只被叫一次.实际上它使用迭代器来完成这个技巧.
此外,在你的情况下,我认为你应该使用
for (Map.Entry<String, String> entry : myMap.entrySet())
{
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
Run Code Online (Sandbox Code Playgroud)
避免每次在地图中搜索.
keySet()
只被召唤一次."增强的for循环"基于Iterable
接口,它用于获取a Iterator
,然后用于循环.甚至不可能以Set
任何其他方式迭代a ,因为没有索引或任何可以获得单个元素的东西.
然而,你真正应该做的是完全放弃这种微优化的担忧 - 如果你遇到真正的性能问题,那么你自己从未想过的机会大约是99%.
答案是在Java语言规范中,不需要反编译:)这是我们可以阅读的有关增强的for语句的内容:
增强的for语句具有以下形式:
Run Code Online (Sandbox Code Playgroud)EnhancedForStatement: for ( VariableModifiersopt Type Identifier: Expression) Statement
Expression必须具有类型
Iterable
,否则它必须是数组类型(第10.1节),否则会发生编译时错误.在增强
for
语句(第14.14节)的FormalParameter部分中声明的局部变量的范围是包含的Statement增强
for
陈述的含义通过翻译成基本for
陈述给出.如果类型
Expression
是子类型Iterable
,那么让我们I
成为表达式Expression的类型 .iterator()
.增强for
语句等同于for
表单的基本语句:Run Code Online (Sandbox Code Playgroud)for (I #i = Expression.iterator(); #i.hasNext(); ) { VariableModifiersopt Type Identifier = #i.next(); Statement }
#i
编译器生成的标识符在何处是与增强的for语句发生时的范围(第6.3节)中的任何其他标识符(编译器生成的或其他标识符)不同.否则,Expression必须具有数组类型,
T[]
.让L1 ... Lm
立即增强前标签的(可能为空)顺序for
发言.然后,增强的for语句的含义由以下基本for
语句给出:Run Code Online (Sandbox Code Playgroud)T[] a = Expression; L1: L2: ... Lm: for (int i = 0; i < a.length; i++) { VariableModifiersopt Type Identifier = a[i]; Statement }
其中a和i是编译器生成的标识符,它们与发生增强for语句的范围内的任何其他标识符(编译器生成的或其他标识符)不同.
在您的情况下,myMap.keySet()
返回一个子类型,Iterable
以便您的增强for
语句等效于以下基本for
语句:
for (Iterator<String> iterator = myMap.keySet().iterator(); iterator.hasNext();) {
String key = iterator.next();
System.out.println(key);
System.out.println(myMap.get(key));
}
Run Code Online (Sandbox Code Playgroud)
并myMap.keySet()
由此被称为只有一次.
归档时间: |
|
查看次数: |
14360 次 |
最近记录: |