Java for循环优化(Java for-loop optimization)
我用java for循环做了一些运行时测试,并认识到了一个奇怪的行为。 对于我的代码,我需要像int,double等基本类型的包装对象来模拟io和输出参数,但那不是重点。 只需看我的代码。 具有字段访问权限的对象如何比原始类型更快?
具有prtimitive类型的
for
循环:public static void main(String[] args) { double max = 1000; for (int j = 1; j < 8; j++) { double i; max = max * 10; long start = System.nanoTime(); for (i = 0; i < max; i++) { } long end = System.nanoTime(); long microseconds = (end - start) / 1000; System.out.println("MicroTime primitive(max: ="+max + "): " + microseconds); } }
结果:
MicroTime原语(最大值:= 10000.0):110
MicroTime原语(最大值:= 100000.0):1081
MicroTime原语(最大值:= 1000000.0):2450
MicroTime原语(max:= 1.0E7):28248
MicroTime原语(最大值:= 1.0E8):276205
MicroTime原语(最大:= 1.0E9):2729824
MicroTime原语(最大值= 1.0E10):27547009
for
loop with simple type(wrapper object):public static void main(String[] args) { HDouble max = new HDouble(); max.value = 1000; for (int j = 1; j < 8; j++) { HDouble i = new HDouble(); max.value = max.value*10; long start = System.nanoTime(); for (i.value = 0; i.value <max.value; i.value++) { } long end = System.nanoTime(); long microseconds = (end - start) / 1000; System.out.println("MicroTime wrapper(max: ="+max.value + "): " + microseconds); } }
结果:
MicroTime封装(最大:= 10000.0):157
MicroTime包装器(最大值:= 100000.0):1561
MicroTime包装器(最大值:= 1000000.0):3174
MicroTime包装器(最大值:= 1.0E7):15630
MicroTime包装器(最大值:= 1.0E8):155471
MicroTime包装器(最大值:= 1.0E9):1520967
MicroTime包装器(最大值:= 1.0E10):15373311迭代次数越多,第二个代码就越快。 但为什么? 我知道java编译器和jvm正在优化我的代码,但我从来没有想过,基元类型可能比有字段访问的对象慢。
有人有合理的解释吗?编辑:HDouble类:
public class HDouble { public double value; public HDouble() { } public HDouble(double value) { this.value = value; } @Override public String toString() { return String.valueOf(value); } }
我还用代码测试了我的循环。 例如,我计算总和 - >相同的行为(差异不是那么大,但我认为原始算法必须更快?)。 首先我想,计算需要很长时间,这个领域几乎没有区别。
包装for循环:
for (i.value = 0; i.value <max.value; i.value++) { sum.value = sum.value + i.value; }
结果:
MicroTime包装器(最大值:= 10000.0):243
MicroTime包装器(最大值:= 100000.0):2805
MicroTime包装器(最大值:= 1000000.0):3409
MicroTime包装器(最大值:= 1.0E7):28104
MicroTime包装器(最大值:= 1.0E8):278432
MicroTime封装(最大= 1.0E9):2678322
MicroTime包装器(最大值:= 1.0E10):26665540原始for循环:
for (i = 0; i < max; i++) { sum = sum + i; }
结果:
MicroTime基元(最大值= 10000.0):149
MicroTime基元(最大:= 100000.0):1996
MicroTime原语(最大值:= 1000000.0):2289
MicroTime原语(最大值:= 1.0E7):27085
MicroTime原语(最大值:= 1.0E8):279939
MicroTime原语(最大值= 1.0E9):2759133
MicroTime原语(最大值:= 1.0E10):27369724I made some runtime tests with java for loops and recognized a strange behaviour. For my code I need wrapper objects for primitive types like int, double and so on, to simulate io and output parameters, but thats not the point. Just watch my code. How can objects with field access be faster then primitive types?
for
loop with prtimitive type:public static void main(String[] args) { double max = 1000; for (int j = 1; j < 8; j++) { double i; max = max * 10; long start = System.nanoTime(); for (i = 0; i < max; i++) { } long end = System.nanoTime(); long microseconds = (end - start) / 1000; System.out.println("MicroTime primitive(max: ="+max + "): " + microseconds); } }
Result:
MicroTime primitive(max: =10000.0): 110
MicroTime primitive(max: =100000.0): 1081
MicroTime primitive(max: =1000000.0): 2450
MicroTime primitive(max: =1.0E7): 28248
MicroTime primitive(max: =1.0E8): 276205
MicroTime primitive(max: =1.0E9): 2729824
MicroTime primitive(max: =1.0E10): 27547009
for
loop with simple type (wrapper object):public static void main(String[] args) { HDouble max = new HDouble(); max.value = 1000; for (int j = 1; j < 8; j++) { HDouble i = new HDouble(); max.value = max.value*10; long start = System.nanoTime(); for (i.value = 0; i.value <max.value; i.value++) { } long end = System.nanoTime(); long microseconds = (end - start) / 1000; System.out.println("MicroTime wrapper(max: ="+max.value + "): " + microseconds); } }
Result:
MicroTime wrapper(max: =10000.0): 157
MicroTime wrapper(max: =100000.0): 1561
MicroTime wrapper(max: =1000000.0): 3174
MicroTime wrapper(max: =1.0E7): 15630
MicroTime wrapper(max: =1.0E8): 155471
MicroTime wrapper(max: =1.0E9): 1520967
MicroTime wrapper(max: =1.0E10): 15373311The more iterations, the faster is the second code. But why? I know that the java-compiler and jvm are optimizing my code, but I never thought that primitive types can be slower, than objects with field access.
Does anyone have a plausible explanation for it?Edited: HDouble class:
public class HDouble { public double value; public HDouble() { } public HDouble(double value) { this.value = value; } @Override public String toString() { return String.valueOf(value); } }
I also tested my loops with code in it. For example I calculate the sum -> same behaviour (the difference is not that big, but I thought the primitive algorithm have to be much faster?). First I thought, that the calculation takes that long, that the field access nearly no difference.
Wrapper for-loop:
for (i.value = 0; i.value <max.value; i.value++) { sum.value = sum.value + i.value; }
Result:
MicroTime wrapper(max: =10000.0): 243
MicroTime wrapper(max: =100000.0): 2805
MicroTime wrapper(max: =1000000.0): 3409
MicroTime wrapper(max: =1.0E7): 28104
MicroTime wrapper(max: =1.0E8): 278432
MicroTime wrapper(max: =1.0E9): 2678322
MicroTime wrapper(max: =1.0E10): 26665540Primitive for-loop:
for (i = 0; i < max; i++) { sum = sum + i; }
Result:
MicroTime primitive(max: =10000.0): 149
MicroTime primitive(max: =100000.0): 1996
MicroTime primitive(max: =1000000.0): 2289
MicroTime primitive(max: =1.0E7): 27085
MicroTime primitive(max: =1.0E8): 279939
MicroTime primitive(max: =1.0E9): 2759133
MicroTime primitive(max: =1.0E10): 27369724
原文:https://stackoverflow.com/questions/33842116
最满意答案
在Python 2.x上,您需要使用
raw_input()
而不是input()
。 在旧版本的Python上,input()
实际上会评估您键入的内容,这就是您需要引号的原因(就像您在Python程序中编写字符串一样)。Python 3.x和Python 2.x之间存在许多差异; 这只是其中之一。 但是,您可以使用以下代码解决此特定差异 :
try: input = raw_input except NameError: pass # now input() does the job on either 2.x or 3.x
On Python 2.x you need to be using
raw_input()
rather thaninput()
. On the older version of Python,input()
actually evaluates what you type as a Python expression, which is why you need the quotes (as you would if you were writing the string in a Python program).There are many differences between Python 3.x and Python 2.x; this is just one of them. However, you could work around this specific difference with code like this:
try: input = raw_input except NameError: pass # now input() does the job on either 2.x or 3.x
相关问答
更多-
假设您很乐意将值'na'替换为None ,或者更一般地说,将任何非浮动外观文本替换为None ,那么您可以执行以下操作: def converter(x): try: return float(x) except ValueError: return None alist = [converter(x) for x in alist] 这会将任何内容转换为浮点数。 所以,就目前而言,这也将现有数字转换为浮点数: >>> [converter(x) for ...
-
我喜欢使用用于插值或者是自然语言消息的字符串的双引号,以及用于小符号的字符串的单引号,但如果字符串包含引号,或者如果我忘记,则会打破规则。 对于正则表达式,即使不需要,我也使用三重双引号将文本字符串和原始字符串文字。 例如: LIGHT_MESSAGES = { 'English': "There are %(number_of_lights)s lights.", 'Pirate': "Arr! Thar be %(number_of_lights)s lights." } def l ...
-
试试这个(未经测试): tr -d "\"" < input > output Try this (untested): tr -d "\"" < input > output
-
我确实看过小提琴,唯一可以获得你想要的行为的方法是通过字面分离,克隆和重新插入字段。 工作。 $('.removeReq').click(function() { var password = $('#password').removeAttr('required oninvalid oninput pattern').detach().clone(); $('form').prepend(password); }); https://jsfiddle.net/t1p1wub3/2/ I did ...
-
Python删除引号(Python removing quotes)[2022-07-04]
Python的str.replace()不会修改字符串。 这意味着,为了使任何事情发生,您需要将结果分配给变量。 例如: string1 = "foo" string2 = string1.replace("foo", "bar") print(string1) >>> "foo" print(string2) >>> "bar" string1保持不变, string2具有修改后的值。 所以在你的情况下你想要: des = des.replace('"', '') Python's str.rep ... -
我个人认为这段代码是正确和安全的,但你应该非常怀疑使用这样的代码而不是自己或者(更好)在安全专家的帮助下仔细检查它。 我没资格成为这样的专家。 我改变了两件重要事情: 我将b = '0'更改为b = 0因此它最终为数字而不是带引号的字符串。 (这部分很容易解决。) 我跳过了列名的内置参数化,并将其替换为我对mysql-connector内置的转义/引用的略微修改。 这是可以让你停下来的可怕部分。 下面的完整代码,但如果列名是用户输入,请再次注意! import mysql.connector def es ...
-
在Python 2.x上,您需要使用raw_input()而不是input() 。 在旧版本的Python上, input()实际上会评估您键入的内容,这就是您需要引号的原因(就像您在Python程序中编写字符串一样)。 Python 3.x和Python 2.x之间存在许多差异; 这只是其中之一。 但是,您可以使用以下代码解决此特定差异 : try: input = raw_input except NameError: pass # now input() does the job o ...
-
删除对象所需的错误(Removing object required errors)[2023-12-12]
你变量( R和rng )不一致,你应该使用 If TypeName(R) <> "Range" Then 这就是说,建议你尝试检查一个有效的范围如下: Dim R As Range On Error Resume Next Set R = Application.InputBox("Select cells To be deleted", , , , , , , 8) On Error GoTo 0 If R Is Nothing Then MsgBo ... -
所有Python容器(包括集合)都使用repr()来显示其内容; 这意味着成为调试助手 ,开发者代表,而不是给最终用户的东西。 因此,如果您想在不使用repr()情况下显示内容,则需要手动设置字符串的格式。 例如: def set_representation(s): return '{{{}}}'.format(', '.join(map(str, s))) 使用逗号将它们映射到str()然后用{...}大括号括起来。 这产生: >>> s = {'abc', 'def', 'ghi'} >>> ...
-
我想你想用引用来自几个标签的字符串替换quotes数组中的(randomuser)。 在这种情况下,您可以获得这些输入的内容,如下所示: var user1 = document.getElementById("input1").value; var user2 = document.getElementById("input2").value; 现在,您可以使用String.replace()替换那些输入值的“(randomuser1)”和“(randomuser2)”,如下所示: //S ...