首页 \ 问答 \ Java for循环优化(Java for-loop optimization)

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):27369724


I 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): 15373311

The 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): 26665540

Primitive 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
更新时间:2023-09-10 18:09

最满意答案

在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 than input(). 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的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 ...
  • 你变量( 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 ...

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)