最近不是一直在搞优化吗,为的就是提高项目的处理能力,提高吞吐量。然后就各种搜呀,各种JProfiler测试。看看代码有啥可优化的。总能看到一个观点。

final修饰类或者方法,能是性能提高50%。

大师兄

不止一次,见到这个观点。这个是真的吗?

我来测试一下

1,先看下加final的方法和不加的差别

大师兄

看不出来50%在哪里。

使用的测试代码:

main方法

package com.lxk.fast; 
 
import com.google.common.collect.Lists; 
import com.lxk.model.Car; 
import com.lxk.model.CarFinal; 
import com.lxk.model.Dog; 
 
/** 
 * 有人说给方法或者类加上final之后,效率会提升,我来试试。 
 * 
 * @author LiXuekai on 2019/6/20 
 */ 
public class IsFinalFast { 
    public static void main(String[] args) { 
        methodTest(); 
        //classTest(); 
    } 
 
    private static void classTest() { 
        while (true) { 
            classFinal(); 
            classNoFinal(); 
        } 
    } 
 
    private static void classFinal() { 
        CarFinal car = new CarFinal("oooo", 100, Lists.newArrayList(new Dog("aaa", true, true))); 
        car.finalRun(); 
    } 
 
    private static void classNoFinal() { 
        Car car = new Car("oooo", 100, Lists.newArrayList(new Dog("aaa", true, true))); 
        car.run(); 
    } 
 
    private static void methodTest() { 
        Car car = new Car("oooo", 100, Lists.newArrayList(new Dog("aaa", true, true))); 
        while (true) { 
            noFinal(car); 
            isFinal(car); 
        } 
    } 
 
    private static void isFinal(Car car) { 
        car.finalRun(); 
    } 
 
    private static void noFinal(Car car) { 
        car.run(); 
    } 
} 

使用的2个model类

Car.java

package com.lxk.model; 
 
import com.google.common.collect.Lists; 
import lombok.AllArgsConstructor; 
import lombok.Data; 
import lombok.NoArgsConstructor; 
 
import java.io.Serializable; 
import java.util.List; 
 
@Data 
@AllArgsConstructor 
@NoArgsConstructor 
public class Car implements Cloneable, Comparable<Car> , Serializable { 
    private String sign; 
    private int price; 
    private List<Dog> myDog; 
    private List<String> boys; 
 
 
    public Car(String sign, int price) { 
        this.sign = sign; 
        this.price = price; 
    } 
 
    public Car(String sign, int price, List<Dog> myDog) { 
        this.sign = sign; 
        this.price = price; 
        this.myDog = myDog; 
    } 
 
    @Override 
    public int compareTo(Car o) { 
        //同理也可以根据sign属性排序,就不举例啦。 
        return this.getPrice() - o.getPrice(); 
    } 
 
    @Override 
    public String toString() { 
        return "Car{" + 
                "sign='" + sign + '\'' + 
                ", price=" + price + 
                ", myDog=" + myDog + 
                ", boys=" + boys + 
                '}'; 
    } 
 
    @Override 
    public Car clone() { 
        Car car = null; 
        try { 
            car = (Car) super.clone(); 
            if (myDog != null) { 
                car.setMyDog(Lists.newArrayList(myDog)); 
            } 
            if (boys != null) { 
                car.setBoys(Lists.newArrayList(boys)); 
            } 
        } catch (CloneNotSupportedException ignored) { 
            System.out.println(ignored.getMessage()); 
        } 
        return car; 
    } 
 
    public void run() { 
        for (int i = 0; i < 1000; i++) { 
            func(); 
        } 
    } 
 
    public final void finalRun() { 
        for (int i = 0; i < 1000; i++) { 
            func1(); 
        } 
    } 
 
    final void func1() { 
        String s = this.toString(); 
    } 
 
    void func() { 
        String s = this.toString(); 
    } 
}

CarFinal.java

package com.lxk.model; 
 
 
import com.google.common.collect.Lists; 
import lombok.AllArgsConstructor; 
import lombok.Data; 
import lombok.NoArgsConstructor; 
 
import java.io.Serializable; 
import java.util.List; 
 
/** 
 * 使用final的Car类 
 * 
 * @author LiXuekai on 2019/6/20 
 */ 
@Data 
@AllArgsConstructor 
@NoArgsConstructor 
public final class CarFinal implements Cloneable, Comparable<Car>, Serializable { 
    private String sign; 
    private int price; 
    private List<Dog> myDog; 
    private List<String> boys; 
 
 
    public CarFinal(String sign, int price) { 
        this.sign = sign; 
        this.price = price; 
    } 
 
    public CarFinal(String sign, int price, List<Dog> myDog) { 
        this.sign = sign; 
        this.price = price; 
        this.myDog = myDog; 
    } 
 
    @Override 
    public int compareTo(Car o) { 
        //同理也可以根据sign属性排序,就不举例啦。 
        return this.getPrice() - o.getPrice(); 
    } 
 
    @Override 
    public String toString() { 
        return "Car{" + 
                "sign='" + sign + '\'' + 
                ", price=" + price + 
                ", myDog=" + myDog + 
                ", boys=" + boys + 
                '}'; 
    } 
 
    @Override 
    public Car clone() { 
        Car car = null; 
        try { 
            car = (Car) super.clone(); 
            if (myDog != null) { 
                car.setMyDog(Lists.newArrayList(myDog)); 
            } 
            if (boys != null) { 
                car.setBoys(Lists.newArrayList(boys)); 
            } 
        } catch (CloneNotSupportedException ignored) { 
            System.out.println(ignored.getMessage()); 
        } 
        return car; 
    } 
 
    public void run() { 
        for (int i = 0; i < 1000; i++) { 
            func(); 
        } 
    } 
 
    public final void finalRun() { 
        for (int i = 0; i < 1000; i++) { 
            func1(); 
        } 
    } 
 
    final void func1() { 
        String s = this.toString(); 
    } 
 
    void func() { 
        String s = this.toString(); 
    } 
} 

2,使用final 的类和没final的类的差别。

就是把上面的main方法换第二个执行。

大师兄

也不是很大的差距呀。

没有传说中的50%的性能提升呀。

是我测试姿势不对么?代码写的哪里有问题么?

大师兄

这个解释怎么样?

就像人类的认知,很久之前,以为地球是中心,太阳围着地球,那个时候,“太阳围着地球转”这个理论是对的。

但是,时间久了,新发现,新科技,新认知之后,“太阳围着地球转”的理论就out了。

这个理论适用这个“final”优化吗?


发布评论
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

Java 代码优化 字符串高效率拼接:+,contact,StringBuffer,StringBuilder 的性能比较,使用JProfiler测试知识解答
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。