Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

面向过程 :面向过程性能比面向对象高?? #431

Open
ryouaki opened this issue Aug 8, 2019 · 34 comments
Open

面向过程 :面向过程性能比面向对象高?? #431

ryouaki opened this issue Aug 8, 2019 · 34 comments
Labels

Comments

@ryouaki
Copy link

@ryouaki ryouaki commented Aug 8, 2019

面向过程 :面向过程性能比面向对象高。 因为类调用时需要实例化,开销比较大,比较消耗资源,所以当性能是最重要的考量因素的时候,比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发。

----》》
这个并不是根本原因,面向过程也需要分配内存,计算内存偏移量,Java性能差的主要原因并不是因为它是面向对象语言,而是Java是半编译语言,最终的执行代码并不是可以直接被CPU执行的二进制机械码。

而面向过程语言大多都是直接编译成机械码在电脑上执行,并且其它一些面向过程的脚本语言性能也并不一定比Java好。

@guang19
Copy link
Contributor

@guang19 guang19 commented Aug 11, 2019

@ryouaki 感谢,学习了

@guang19
Copy link
Contributor

@guang19 guang19 commented Aug 18, 2019

我觉得这个得分情况而定,c和c++就是很好的例子,两种语言执行效率差距其实并不大,但是两种语言的设计思想就不同。

@ryouaki
Copy link
Author

@ryouaki ryouaki commented Aug 18, 2019

@ryouaki 请教一下,是不是可以概括为:“程序的性能首先由编程语言的执行方式有关,其次才是设计范式”

设计范式和性能无关的。主要是编程语言的运行机制决定的。

@ryouaki
Copy link
Author

@ryouaki ryouaki commented Aug 18, 2019

我觉得这个得分情况而定,c和c++就是很好的例子,两种语言执行效率差距其实并不大,但是两种语言的设计思想就不同。

c和c++的运行机制是一样的。都是编译成机械码。

@guang19
Copy link
Contributor

@guang19 guang19 commented Aug 18, 2019

感谢

@321cto
Copy link

@321cto 321cto commented Sep 1, 2019

收益了,感谢

@LiuRuiXiang
Copy link

@LiuRuiXiang LiuRuiXiang commented Sep 5, 2019

长知识了

@rockhu01
Copy link

@rockhu01 rockhu01 commented Nov 22, 2019

学习了

@Lotus-Blue
Copy link

@Lotus-Blue Lotus-Blue commented Nov 22, 2019

amazing gay

@konigsbergg
Copy link

@konigsbergg konigsbergg commented Dec 3, 2019

good job

@codingKings
Copy link

@codingKings codingKings commented Dec 7, 2019

到底是面向过程性能高还是面向对象性能高?这类问题很难回答,非要比较高低的话就必须设定一个场景,否则只能说是各有所长

@peacecoder
Copy link

@peacecoder peacecoder commented Dec 19, 2019

另外,现在java 性能不一定低,变化很大了

@ryouaki
Copy link
Author

@ryouaki ryouaki commented Dec 20, 2019

另外,现在java 性能不一定低,变化很大了

上半年刚测的。

@cjjMichael
Copy link

@cjjMichael cjjMichael commented Dec 31, 2019

感觉这个表述-"而是Java是半编译语言,最终的执行代码并不是可以直接被CPU执行的二进制机械码"不是很准确。最终执行代码不都是二进制码吗?(在此之前是低级语言代码,如汇编)个人觉得可以表述为编译过程的复杂程度的不同导致执行时间的不同(性能的主要度量)。第二,直接比较语言性能本来就是不恰当的。第三,现在的Java今非昔比,底层编译更加优化。第四,有限的测试不具有说服力,具体情况具体分析。

@cjjMichael
Copy link

@cjjMichael cjjMichael commented Dec 31, 2019

修正一下是"中间语言代码"。

@haichuanjiang
Copy link

@haichuanjiang haichuanjiang commented Jan 5, 2020

可以

@yongmingcode
Copy link

@yongmingcode yongmingcode commented Mar 8, 2020

谢谢,学习了

@Snailclimb Snailclimb reopened this Mar 9, 2020
@zenglanyuan
Copy link

@zenglanyuan zenglanyuan commented Mar 17, 2020

讨论比回答更精彩。哈哈哈

@makronyang
Copy link

@makronyang makronyang commented Mar 24, 2020

java 是解释语言 执行的时候 比直接 编译出来的 二进制执行码多了一个步骤

@zhangzuyi
Copy link

@zhangzuyi zhangzuyi commented Mar 30, 2020

学习中

@ttr5966
Copy link

@ttr5966 ttr5966 commented Mar 30, 2020

@iloooo
Copy link

@iloooo iloooo commented Apr 2, 2020

@Snailclimb
“1. 面向对象和面向过程的区别”, 根据guide中解释的内容我觉得应该是面向对象和面向过程优缺点更准确些,而它们两个区别应该讨论OOP和POP解决问题的方式不同。
面向过程解决问题方式:把解决问题的过程,拆成一个个方法,通过一个个方法的执行解决问题。
面向对象解决问题方式:先抽象出对象,然后用对象执行方法的方式解决问题。
@ryouaki
我还想补充讨论下,首先面向过程和对象是一种编程思想,就像@cjjMichael 所言“直接比较语言性能本来就是不恰当的”,语言执行性能应该从他们最终执行方式上讨论。直接编译成机器码,然后执行的语言(比如C,编译器一次性编译为平台相关的机器码),从过程复杂度上,肯定比解释执行的语言(HTML,JavaScript,浏览器的解释器,把代码一行行解释为机器码)和 Java这种中间码(编译)+虚拟机(解释成机器码)的方式,要性能高的多。

@yuanjinzhong
Copy link

@yuanjinzhong yuanjinzhong commented Apr 2, 2020

惊呆了

@wangpeipei90
Copy link

@wangpeipei90 wangpeipei90 commented Apr 2, 2020

同意。语言的执行方式和OOP/POP没有必然的关系。从原理上来讲,OOP的语言也可以直接编译成字节码,而POP的语言也可以解释执行。

@907739769
Copy link

@907739769 907739769 commented Apr 19, 2020

个人理解:JAVA为了一次代码,处处运行(也就是可移植性),有了一层中间码也就是字节码,字节码的作用就是为了可移植性,字节码转换成机器码的工作就交给了java虚拟机,由java虚拟机解释成机器能够运行的二进制机器码。而C语言是直接编译为机器码,机器只需要直接运行二进制机器码即可,而无需和java一样在运行时解释为机器码。从这个角度看,性能与面向过程或对象是无关的。(JAVA只是为了移植性舍弃了一部分性能。)

@mjiuming
Copy link

@mjiuming mjiuming commented Apr 19, 2020

其实感觉编程范式的侧重点并不在于性能,在于“通过限制你可能出错的细节而给你更多的自由空间”,在Robert.C.Martin的《架构简洁之道》中第三章末尾有对编程范式进行总结

结构化编程对程序控制权的直接转移进行了限制和规范

面向对象编程对程序控制权的间接转移进行了限制和规范

函数式编程对程序中的赋值进行了限制和规范

每一种编程范式都从某一方面限制和规范了程序员的能力。没有一个范式是增加新能力的。

其实也可以这么理解。通过限制goto的使用,我们可以不必在意程序控制权的跳转细节,从而给我们带来了更多的灵活性。通过封装对象的状态,我们可以安全地控制对象所处状态的有效性,从而可以使用更多设计模式。通过限制属性的赋值,我们可以写出无状态的函数与服务,这样就不逼关心函数的可见性与数据一致性,从而更方便地扩展服务。

@mjiuming
Copy link

@mjiuming mjiuming commented Apr 19, 2020

编程范式是与具体语言无关的,比如说下面这段代码是使用C语言实现的,这段代码是OOP的,因为它满足继承、封装、多态三个特性,但是它的所有语法使用的都是标准C99语法,执行性能与面向过程的C语言代码没有区别

#include <stdio.h>
#include <stdlib.h>

struct Object
{
    int a;
    void (*setA)(struct Object *object, int a);
    int (*getA)(struct Object *object);
};

struct ObjectExtended
{
    struct Object *__super;
    void (*setA)(struct Object *object, int a);
    int (*getA)(struct Object *object);
};

static void _setA(struct Object *object, int a)
{
    object->a = a;
}

static int _getA(struct Object *object)
{
    return object->a;
}

static void _setA_extended(struct Object *object, int a)
{
    printf("ObjectExtended[%p] set A : %d\n", object, a);
    object->a = a;
}

static int _getA_extended(struct Object *object)
{
    printf("ObjectExtended[%p] get A : %d\n", object, object->a);
    return object->a;
}

struct Object *createObject()
{
    struct Object *object = malloc(sizeof(struct Object));
    object->setA = _setA;
    object->getA = _getA;
    return object;
}

struct ObjectExtended *createObjectExtended()
{
    struct Object *object = malloc(sizeof(struct Object));
    struct ObjectExtended *objectExtended = malloc(sizeof(struct ObjectExtended));
    objectExtended->__super = object;
    objectExtended->setA = object->setA = _setA_extended;
    objectExtended->getA = object->getA = _getA_extended;
    return objectExtended;
}

int main(int argc, char **argv)
{
    struct Object *object = createObject();
    struct Object *objectExtended = createObjectExtended();

    object->setA(object, 1);
    printf("Object[%p]->getA() = %d;\n", object, object->getA(object));

    objectExtended->setA(objectExtended, 2);
    printf("Object[%p]->getA() = %d;\n", objectExtended, objectExtended->getA(objectExtended));
    
    return EXIT_SUCCESS;
}

这是运行的输出结果

Object[0x7faeb6c017c0]->getA() = 1;
ObjectExtended[0x7faeb6c01800] set A : 2
ObjectExtended[0x7faeb6c01800] get A : 2
Object[0x7faeb6c01800]->getA() = 2;
@shitsurei
Copy link

@shitsurei shitsurei commented Apr 22, 2020

学习了

@wangbaojiao
Copy link

@wangbaojiao wangbaojiao commented May 6, 2020

JRocket、Hot Spot jit都是将字节码编译为机器语言,所以我觉的慢除了和解释执行有一定关系;
还和基于栈的指令集有关(机器指令集是基于寄存器的),基于栈的访问内存效率低于寄存器的;
还和设计范式有关(比如较强的内存模型)。

@JerryQiang
Copy link
Contributor

@JerryQiang JerryQiang commented May 11, 2020

关于关键词,应该是机器码,而不是机械码

@mirror6Y
Copy link

@mirror6Y mirror6Y commented May 22, 2020

get!

@kfw5264
Copy link

@kfw5264 kfw5264 commented May 25, 2020

涨姿势了

@womingzhiren
Copy link

@womingzhiren womingzhiren commented Jun 20, 2020

语言的性能与是否面向过程或者面向对象无关,大部分看语言的执行方式,我觉得性能大概是机器码(不用编译)>C,C++(编译)>java(半编译半解释)>html(解释)

@mjiuming
Copy link

@mjiuming mjiuming commented Jun 20, 2020

硬件场合下决定是否使用某语言的关键因素并不是性能因素,而是这个语言是否是实时性的,而不是使用了何种编程范式。

对于C语言和C++语言来说,所有内存资源的申请与释放都是手动进行的,所有的指令都是以程序员期望的顺序以相同的指令周期顺序执行。

对于Java语言和Golang语言等带自动垃圾回收语言来说,程序会在不适当的时机暂停线程来执行垃圾回收。对于某些任务来说可能期望在几个指令周期内接受所有外部信号并处理完成,在这种情况下暂停线程并执行垃圾回收就会导致信号的丢失。

至于说面向对象与面向过程的性能差异,我上面给出了使用C语言实现面向对象的示例了,而在Linux内核中也大量使用OOP范式来实现对硬件资源的抽象,所以说性能差异是来自于这个语言的执行机制,而不是这个语言采用的编程范式。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.