Java 动态创建对象与将对象存储为字段
我有一个循环,大约运行1000000次Java 动态创建对象与将对象存储为字段,java,performance,object,Java,Performance,Object,我有一个循环,大约运行1000000次 while ((line = br.readLine()) != null) { if(!(line.isEmpty())){ data = new JSONObject(line); name = (String)data.get("name");
while ((line = br.readLine()) != null) {
if(!(line.isEmpty())){
data = new JSONObject(line);
name = (String)data.get("name");
surname = (String)data.get("surname");
ar.put(name, surname); //an array
}
}
与在运行时创建一个新的动态对象相比,将数据、名称和姓氏字段设置为那样在效率方面有哪些优势(如果有的话)
while ((line = br.readLine()) != null) {
if(!(line.isEmpty())){
JSONObject data = new JSONObject(line);
String name = (String)data.get("name");
String surname = (String)data.get("surname");
ar.put(name, surname); //an array
}
}
不会有任何区别,因为您只更改了变量的范围。由于您没有使用范围之外的变量,因此生成的字节码也将是相同的(您可以使用
javap
进行尝试)
因此,为了清晰起见,请使用第二种样式
编辑:事实上,如果将变量作为类的字段,则字节码可能不同。性能将取决于JIT最终如何实现,但不太可能存在显著差异(即使如此,第二种方法也更容易优化->可能更快)。不会有任何差异,因为您只更改了变量的范围。由于您没有使用范围之外的变量,因此生成的字节码也将是相同的(您可以使用
javap
进行尝试)
因此,为了清晰起见,请使用第二种样式
编辑:事实上,如果将变量作为类的字段,则字节码可能不同。性能将取决于JIT最终如何实现,但不太可能存在显著差异(即使如此,第二种方法也更容易优化->可能更快)。第一种方法应该执行得更快,因为它对每个变量(数据、名称、姓氏)使用一个引用对于每个循环
而第二种方法为每个循环中的每个循环创建一个新的引用。因此,您最终会创建每一个的一百万个引用 然而,创建引用是一个恒定的时间操作,不应该打扰您。您应该专注于使代码可读和干净。因此,由于最佳实践表明变量的范围尽可能小,如果我知道此方法将运行多次,我只会选择第一种方法。(我的意思是,如果它只运行一次,你可以再等几毫秒) 性能提示:由于您关心性能,并且您大致知道迭代次数,我建议您初始化
映射的容量第一种方法应该执行得更快,因为它对每个变量使用一个引用(数据、名称、姓氏)用于每个循环
而第二种方法为每个循环中的每个循环创建一个新的引用。因此,每个循环都会创建一百万个引用
然而,创建引用是一个固定时间的操作,不应该打扰您。您应该专注于使代码可读和干净。因此,由于最佳实践建议变量的范围尽可能小,如果我知道此方法将运行多次,我只会选择第一种方法。(我的意思是,如果它只运行一次,你可以再等几毫秒)
性能提示:由于您关心性能,并且您大致知道迭代次数,因此我建议您初始化映射的容量
,即使在GC过程中也不初始化。您创建的对象数量相同,因此GC不太可能受到影响。GC是什么要在这里清理吗?您将它们存储在一个数组中,因此仍然引用它们。但是,如果您不存储它们,GC将以相同的方式在两个示例中进行清理。听起来很反直觉,第二个版本在GC的微观细节方面可能更快(尽管它实际上不会影响垃圾收集)。在某些GC实现中,覆盖对另一个对象的现有引用以指向新对象可能会包括一些额外的分支,如果您只是丢弃引用并创建一个新对象,则可能不需要这些分支。这是非常微观级别的东西,在任何实际测量中都不太可能出现,但值得一提g、 重用相同的引用可能比优化更悲观。请注意,您的问题完全是微观级别的。它不会影响GC,因为它只影响引用,而不会影响GC分配的实际对象。现在,从对象池重用相同的对象将是真正的GC级别优化,这可能会为您带来一些性能nce获得了收益。但简单地重用同一引用会与编译器争夺少量的时钟周期,而且正如Kayaman所指出的,甚至可能会损害性能。如果JIT应用单一静态赋值,那么对同一引用的重新赋值将有效地将它们视为寄存器alloc的单独变量。即使在GC过程中也是如此ess?您正在创建相同数量的对象,因此GC不太可能受到影响。GC将在此处清理什么?您将它们存储在一个数组中,因此仍在引用它们。但是,如果不存储它们,GC将以相同的方式在两个示例中清理。听起来似乎有点违反直觉,第二个版本使用re可能会更快从spect到GC的微观细节(尽管它实际上不会影响垃圾收集)。在某些GC实现中,覆盖对另一个对象的现有引用以指向新对象可能会包括一些额外的分支,如果您只是丢弃引用并创建一个新对象,则可能不需要这些分支。这是非常微观级别的东西,在任何实际测量中都不太可能出现,但值得一提g、 重用相同的引用可能比优化更悲观。请注意,您的问题完全是微观级别的。它不会影响GC,因为它只影响引用,而不会影响GC分配的实际对象。现在,从对象池重用相同的对象将是真正的GC级别优化,这可能会为您带来一些性能nce获得了收益,但只需重复使用相同的r