Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用静态私有方法真的比实例私有方法更快/更好吗?_Java_Performance_Coding Style_Static Methods - Fatal编程技术网

Java 使用静态私有方法真的比实例私有方法更快/更好吗?

Java 使用静态私有方法真的比实例私有方法更快/更好吗?,java,performance,coding-style,static-methods,Java,Performance,Coding Style,Static Methods,我想问的是这样做是否有区别: public Something importantBlMethod(SomethingElse arg) { if (convenienceCheckMethod(arg)) { // do important BL stuff } } private boolean convenienceCheckMethod(SomethingElse arg) { // validate something } 这是: publi

我想问的是这样做是否有区别:

public Something importantBlMethod(SomethingElse arg) {
    if (convenienceCheckMethod(arg)) {
        // do important BL stuff
    }
}

private boolean convenienceCheckMethod(SomethingElse arg) {
    // validate something
}
这是:

public Something importantBlMethod(SomethingElse arg) {
    if (convenienceCheckMethod(arg)) {
        // do important BL stuff
    }
}

private static boolean convenienceCheckMethod(SomethingElse arg) {
    // validate something
}
我实际上使用了选项1,因为它对我来说更自然

那么,第一种方式和第二种方式之间是否存在风格/惯例/性能差异

谢谢


正如我测试它的评论中所建议的,在我的基准测试中,动态方法更快

这是测试代码:

public class Tests {

    private final static int ITERATIONS = 100000;

    public static void main(String[] args) {
        final long start = new Date().getTime();

        final Service service = new Service();
        for (int i = 0; i < ITERATIONS; i++) {

            service.doImportantBlStuff(new SomeDto());
        }

        final long end = new Date().getTime();

        System.out.println("diff: " + (end - start) + " millis");
    }
}
对于100000次迭代,动态方法通过577ms,静态方法通过615ms

然而,这对我来说是不确定的,因为我不知道编译器决定优化什么以及何时优化


这正是我想要了解的。

如果您的方法需要实例数据或对其他实例方法的调用,那么它必须是实例方法

如果函数只依赖于它的参数,而不依赖于其他静态数据,那么它也可以是一个实例方法——这样可以避免在调用静态函数时重复类名

IMHO,没有特别需要使函数
为静态
,除非:

  • 它可以从其他类调用(即非
    private
    ),并且
  • 它不引用实例变量,并且
  • 它引用其他静态类数据

  • 性能方面:差异(如果有的话)可以忽略不计


    经验法则是,如果方法不与其类的任何成员交互,则将其声明为静态

    如果函数的结果只依赖于参数,那么它应该是静态的。如果它依赖于实例,则将其设为实例成员


    这与性能无关;这是关于语义的。除非每秒调用此函数一百万次,否则不会注意到性能差异,即使如此,差异也不会很大。

    这一切都取决于上下文。通常,静态方法/变量在类中声明,以便外部类可以使用它们

    如果要调用本地方法,则通常应使用实例方法,而不是静态调用


    仅供参考,您从实例方法调用静态方法的语法是错误的。您必须提供类名。

    根据我的说法,静态方法的绑定与非静态私有方法相同,即
    早期绑定
    。 . 编译器实际上是在创建字节码时将方法代码(静态或非静态私有)添加到代码中


    更新:刚刚完成。它说实例方法绑定是
    动态的
    ,所以如果方法不是
    非静态私有的
    ,那么。您的静态方法更快。

    可能会,也可能不会。代码的不同执行可能会有所不同

    这里是您在不深入研究热点端口代码(或非热点JVM的代码)的情况下唯一可以知道的事情:

    • 使用调用静态方法,不需要对象引用
    • 使用调用实例私有方法,这确实需要对象引用
    这两个操作码都有一个用于解析要调用的实际方法的过程,并且这些过程相对类似(您可以阅读规范)。如果不计算实际实现的指令,就不可能说哪个更快

    invokespecial
    将一个额外的值推送到堆栈上。这样做的时间以纳秒的分数计算


    使所有这些都成为现实,Hotspot有一系列可以执行的优化。在程序运行期间,它可能不必多次执行实际的方法解析。它可能会选择内联方法(也可能不内联),但成本大致相当。

    我检查了,我希望它能做到您想知道的,代码不会很漂亮:

    public class main {
    
    @SuppressWarnings("all")
    public static void main(String[] args) {
        main ma = new main();
        int count = Integer.MAX_VALUE;
        long beg = (new Date()).getTime();
        for (int i = 0; i < count; i++) {
            ma.doNothing();
        }
        System.out.println("priv : " + new Long((new Date()).getTime() - beg).toString());
    
        beg = (new Date()).getTime();
        for (int i = 0; i < count; i++) {
            doNothingStatic();
        }
        System.out.println("privstat : " + new Long((new Date()).getTime() - beg).toString());
    
    }
    
    private void doNothing() {
        int i = 0;
    }
    
    private static void doNothingStatic() {
        int i = 0;
    }
    }
    
    公共类主{
    @抑制警告(“全部”)
    公共静态void main(字符串[]args){
    main ma=新的main();
    int count=整数最大值;
    long beg=(新日期()).getTime();
    for(int i=0;i
    结果:

    priv:1774
    privstat:1736

    priv:1906
    privstat:1783

    priv:1963
    privstat:1751

    priv:1782
    privstat:1929

    priv:1876
    privstat:1867


    它看起来不像是依赖于静态-非静态私有方法。我确信差异来自于机器当前的负担。

    我参加了编码竞赛,并且我观察到,非静态方法比静态方法更快(无论多么小)。当然,这取决于您的使用和情况要求,但是静态方法与非静态方法相比性能较差。按照惯例,为了便于编写代码,您可以使用静态方法,但是创建类的实例并调用该方法将提供更好的性能。

    您尝试过吗?速度快吗?我想说速度差(不管是什么)不值得权衡哪一个更可读。这与性能无关,但是如果你想单元测试你的代码@david99world,哪一个更可读,使用静态方法是个坏主意?我想说不是这样的,因为
    private
    方法本质上也是
    final
    方法,因此,它与
    static
    方法一样可以静态调用和内联。这不是我要问的:)所以让它静止,一个
    public class main {
    
    @SuppressWarnings("all")
    public static void main(String[] args) {
        main ma = new main();
        int count = Integer.MAX_VALUE;
        long beg = (new Date()).getTime();
        for (int i = 0; i < count; i++) {
            ma.doNothing();
        }
        System.out.println("priv : " + new Long((new Date()).getTime() - beg).toString());
    
        beg = (new Date()).getTime();
        for (int i = 0; i < count; i++) {
            doNothingStatic();
        }
        System.out.println("privstat : " + new Long((new Date()).getTime() - beg).toString());
    
    }
    
    private void doNothing() {
        int i = 0;
    }
    
    private static void doNothingStatic() {
        int i = 0;
    }
    }