-
Notifications
You must be signed in to change notification settings - Fork 45.7k
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
Comments
@ryouaki 感谢,学习了 |
我觉得这个得分情况而定,c和c++就是很好的例子,两种语言执行效率差距其实并不大,但是两种语言的设计思想就不同。 |
设计范式和性能无关的。主要是编程语言的运行机制决定的。 |
c和c++的运行机制是一样的。都是编译成机械码。 |
感谢 |
收益了,感谢 |
长知识了 |
学习了 |
amazing gay |
good job |
到底是面向过程性能高还是面向对象性能高?这类问题很难回答,非要比较高低的话就必须设定一个场景,否则只能说是各有所长 |
另外,现在java 性能不一定低,变化很大了 |
上半年刚测的。 |
感觉这个表述-"而是Java是半编译语言,最终的执行代码并不是可以直接被CPU执行的二进制机械码"不是很准确。最终执行代码不都是二进制码吗?(在此之前是低级语言代码,如汇编)个人觉得可以表述为编译过程的复杂程度的不同导致执行时间的不同(性能的主要度量)。第二,直接比较语言性能本来就是不恰当的。第三,现在的Java今非昔比,底层编译更加优化。第四,有限的测试不具有说服力,具体情况具体分析。 |
修正一下是"中间语言代码"。 |
可以 |
谢谢,学习了 |
讨论比回答更精彩。哈哈哈 |
java 是解释语言 执行的时候 比直接 编译出来的 二进制执行码多了一个步骤 |
学习中 |
性能肯定没有面向过程高 但是面相对象后期的维护 还有扩展性 比面向过程好一点------------------ 原始邮件 ------------------
发件人: "zhangzuyi"<notifications@github.com>
发送时间: 2020年3月30日(星期一) 中午1:08
收件人: "Snailclimb/JavaGuide"<JavaGuide@noreply.github.com>;
抄送: "Subscribed"<subscribed@noreply.github.com>;
主题: Re: [Snailclimb/JavaGuide] 面向过程 :面向过程性能比面向对象高?? (#431)
学习中
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
@Snailclimb |
惊呆了 |
同意。语言的执行方式和OOP/POP没有必然的关系。从原理上来讲,OOP的语言也可以直接编译成字节码,而POP的语言也可以解释执行。 |
个人理解:JAVA为了一次代码,处处运行(也就是可移植性),有了一层中间码也就是字节码,字节码的作用就是为了可移植性,字节码转换成机器码的工作就交给了java虚拟机,由java虚拟机解释成机器能够运行的二进制机器码。而C语言是直接编译为机器码,机器只需要直接运行二进制机器码即可,而无需和java一样在运行时解释为机器码。从这个角度看,性能与面向过程或对象是无关的。(JAVA只是为了移植性舍弃了一部分性能。) |
其实感觉编程范式的侧重点并不在于性能,在于“通过限制你可能出错的细节而给你更多的自由空间”,在Robert.C.Martin的《架构简洁之道》中第三章末尾有对编程范式进行总结
其实也可以这么理解。通过限制goto的使用,我们可以不必在意程序控制权的跳转细节,从而给我们带来了更多的灵活性。通过封装对象的状态,我们可以安全地控制对象所处状态的有效性,从而可以使用更多设计模式。通过限制属性的赋值,我们可以写出无状态的函数与服务,这样就不逼关心函数的可见性与数据一致性,从而更方便地扩展服务。 |
编程范式是与具体语言无关的,比如说下面这段代码是使用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; |
比如来一段 是面向过程开发的代码 和面向对象开发的代码 直接对比看一下! |
函数是否编译于main函数是否调用是没有关系的,比如考虑如下的C语言代码 void foo() {}
void bar() {}
int main(int argc, char **argv) {
return 0;
} 在GCC10.2.0下使用O0优化编译出来汇编代码如下 .file "main.c"
.text
.globl foo
.type foo, @function
foo:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
nop
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size foo, .-foo
.globl bar
.type bar, @function
bar:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
nop
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size bar, .-bar
.globl main
.type main, @function
main:
.LFB2:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl %edi, -4(%rbp)
movq %rsi, -16(%rbp)
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE2:
.size main, .-main
.ident "GCC: (GNU) 10.2.0"
.section .note.GNU-stack,"",@progbits 实际上main入口并没有调用foo和bar,但是编译器依旧会对它进行编译,与你是否有使用过它是没有关系的 XSF notifications@github.com 于2021年1月24日周日 上午12:10写道:
|
试试 o1 o2 o3 编译呢;-O0 不进行优化处理;
…------------------ 原始邮件 ------------------
发件人: "Snailclimb/JavaGuide" <notifications@github.com>;
发送时间: 2021年1月29日(星期五) 中午11:46
收件人: "Snailclimb/JavaGuide"<JavaGuide@noreply.github.com>;
抄送: "193276660"<193276660@qq.com>;"Comment"<comment@noreply.github.com>;
主题: Re: [Snailclimb/JavaGuide] 面向过程 :面向过程性能比面向对象高?? (#431)
函数是否编译于main函数是否调用是没有关系的,比如考虑如下的C语言代码
void foo() {} void bar() {} int main(int argc, char **argv) { return 0; }
在GCC10.2.0下使用O0优化编译出来汇编代码如下
.file "main.c" .text .globl foo .type foo, @function foo: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 nop popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE0: .size foo, .-foo .globl bar .type bar, @function bar: .LFB1: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 nop popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE1: .size bar, .-bar .globl main .type main, @function main: .LFB2: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl %edi, -4(%rbp) movq %rsi, -16(%rbp) movl $0, %eax popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE2: .size main, .-main .ident "GCC: (GNU) 10.2.0" .section .note.GNU-stack,"",@progbits
实际上main入口并没有调用foo和bar,但是编译器依旧会对它进行编译,与你是否有使用过它是没有关系的
XSF notifications@github.com 于2021年1月24日周日 上午12:10写道:
别的地方我还不确定,但是面向对象的搞法内存开销一定是大过面向过程的,比如你上面的C语言面向对象的写法,假设有这么一个类,拥有很多接口,那他就需要很多个函数指针,而你只是想用其中几个接口,但是你在实例化的时候,这些指针变量都会被实例化出来的。以上是第一点,第二点,当你实例化出来你就要赋初值,也就是构造函数的工作,你需要给这些函数指针赋值,那相应地址的函数也会被编译。哪怕你本来不想用这个函数,但是构造函数把他赋值了那个函数就会被编译,同理这个对象中可能还有很多的私有或者公有变量你的程序也用不上。比如女性你只想要她的上半身的功能,但是只要你实例化个女人出来,她的下半身也会存在,在有资源的情况下你为了快速利用别人写好的类,你就直接实例化直接用就完事了多方便啊!但是没资源的情况,用面向过程,需要一个功能函数就调用一个功能函数,没被调用过的函数不会被编译,变量也是看情况声明,不会存在什么明明没用到也被声明出来的情况。linux只能给资源丰富的嵌入式设备用,哪怕是ulinux精简版,中低端单片机基本也用不起,这也是有相应的道理的。
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#431 (comment),
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AKYAXFD2R7GCVMOKRZLHQC3S3LYFVANCNFSM4IKID5KQ
.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
即使是-O3也是同样的 .file "main.c"
.text
.p2align 4
.globl foo
.type foo, @function
foo:
.LFB0:
.cfi_startproc
ret
.cfi_endproc
.LFE0:
.size foo, .-foo
.p2align 4
.globl bar
.type bar, @function
bar:
.LFB4:
.cfi_startproc
ret
.cfi_endproc
.LFE4:
.size bar, .-bar
.section .text.startup,"ax",@progbits
.p2align 4
.globl main
.type main, @function
main:
.LFB2:
.cfi_startproc
xorl %eax, %eax
ret
.cfi_endproc
.LFE2:
.size main, .-main
.ident "GCC: (GNU) 10.2.0"
.section .note.GNU-stack,"",@progbits 除非你对函数签名进行修饰 static void foo() {}
static void bar() {}
int main(int argc, char **argv) {
return 0;
} 明确声明它是不会导出给外部进行调用的函数 .file "main.c"
.text
.section .text.startup,"ax",@progbits
.p2align 4
.globl main
.type main, @function
main:
.LFB2:
.cfi_startproc
xorl %eax, %eax
ret
.cfi_endproc
.LFE2:
.size main, .-main
.ident "GCC: (GNU) 10.2.0"
.section .note.GNU-stack,"",@progbits 只要有非 static void foo() {}
void bar() { foo(); }
int main(int argc, char **argv) {
return 0;
} .file "main.c"
.text
.type foo, @function
foo:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
nop
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size foo, .-foo
.globl bar
.type bar, @function
bar:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $0, %eax
call foo
nop
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size bar, .-bar
.globl main
.type main, @function
main:
.LFB2:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl %edi, -4(%rbp)
movq %rsi, -16(%rbp)
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE2:
.size main, .-main
.ident "GCC: (GNU) 10.2.0"
.section .note.GNU-stack,"",@progbits 当然你可以用static修饰所有不想暴露给别人的函数,但是不觉得这样做就与拿来别人的库来用相违背吗?如果我是给别人用的库,那么我就不可能用static修饰,那么不论我用什么构造函数或不用构造函数都会编译;如果我是给别人用的库,那么我用static修饰了,并且没有使用非 |
请使用阳间的方式沟通,总这么发真的没意思, int a;
int b;
int c;
int d(int){ /* do something */ return 0; }
inf e(int){ /* do something */ return 0; }
inf f(int){ /* do something */ return 0; } 既然你想比较内存优劣请先告诉我这种写法和你那种写法有什么区别,难道这么写就不会占用内存了?请不要和我说你可以不写其他的变量和函数弄成了 int a;
int d(int){ /* do something */ return 0; } 我也可以说为什么我相关的一系列操作不会使用下面的简洁方式呢? typedef struct type {
int a;
int (*d)(int);
} 如果你认为你写的是4K Flash内存的上古芯片,那麻烦老老实实用汇编什么高级语言都别用,最好是没有任何过程调用没有栈帧分配。 除此之外,如果是想好好讨论问题请放在相同的问题域进行讨论,现在在讨论的是用任何语言都能实现面向对象范式,在实现相同功能的情况下大家的执行效率没有明显差异,而不是我使用了封装你非要插入无限多的无用字段然后跟我说:“看,你这个东西占用了无限大的内存,我的只需要一个变量就能完成”,在我眼里就跟有人在跟我说:“火箭这玩意得烧煤,最好还是水洗煤”。 XSF notifications@github.com 于2021年2月3日周三 下午2:41写道:
|
不好意思哈,其实我前面发的刚写完我就都删掉了,因为我对自己回复的结论也不太确定,不知道为什么删掉了你能看见。既然你连着两次都看到了,那我这次不删了 我是这样想的,因为我们面向对象会复用别人或者自己已经写好的类,那在这种情况下,一个类中确确实实有很多你其实并不需要的部分,另外面向对象更改属性也需要通过函数,面向对象为了大型项目多人合作规矩多点,这种编程范式内存怎么想都会占用的大些吧,难道世上真有一个东西只有好处没有一点坏处??? 我主要就是回复楼主,没道理两种编程范式性能一点差别都没有吧,要么面向对象性能强点,要么面向过程强点,反正不可能两个内存占用一毛一样吧 可能是我的错觉,我感觉你在不知不觉中认为我说面向过程更加优越,认为我是在贬低面向对象,其实不是这么回事,我只是实事求是的表达自己对两种语言的看法,优缺点,并没有个人喜好在里面,我看情况都会用。 你这一句也跑题了(现在在讨论的是用任何语言都能实现面向对象范式,在实现相同功能的情况下大家的执行效率没有明显差异)这楼难道不是哪个编程范式性能会高点吗? 4k flash的芯片不是上古啊,单片机中挺常见的,就算不是4k,20k也会优先面向过程吧,单片机领域真的很常见。 我回顾了下我的第一个回复,主要表述的就是内存占用确实会大些,编程范式确实会影响内存。其实这玩意不就像写作吗?写法都不同没理由长度还刚好一样吧。但是,但是,我再再再,强调一次,我没说面向过程比面向对象优越。纯粹的客观讨论,内存占用 再强调一下,大工程要我选我也用面向对象,我回复的是内存的占用吧,就算面向过程内存占用少性能高,我也不可能在大工程里用啊,我不可能给自己找麻烦吧。但是讨论问题事情总要实事求对吧,不可能因为我喜欢用面向对象,就说注重“阅读“”复用”“扩展”的面向对象的内存占用和更紧凑的面向过程也就是算法数据结构的内存占用一致是吧。 千万别跑题,我纯粹的再说内存占用,没有贬低面向对象。和你眼中的“火箭”之类的毛线关系都没有,根据工程来使用,资源少的单片机直接面向过程c,甚至迫不得已写汇编(老板特别抠就会出现这种结果),大工程面向对象。 |
//========================================================= 因为不名原因删除了你还能看见,所以干脆向你请教,纯学习讨论目的 我之前说的话也是结合自己用c去仿写面向对象类,然后我自己使用的过程中的疑惑。但是我并不是很确定以自己的结论(所以删了)。如果你有好的解决方法,还希望告知,我给项目中的单片机专门写了类库,写的还挺全面的,实际使用的时候才发现声明结构体的时候一些我并不打算用的功能也被一起声明了。但是确确实实这样以对象的形式写,很方便,用的时候一个声明,一个构造函数就可以随便用了。我要是面向对象的搞法,做成功能函数,形参会特别长,还要我自己去定义各种专门的数据搭配功能 纯粹学习请教,如何解决这类问题呢? |
struct {
int _1: 1;
int _2: 1;
int _3: 1;
int _4: 1;
int _5: 1;
int _6: 1;
int _7: 1;
int _8: 1;
} P;
// 单片机写法
void main() {
P._1 = 1; // P1引脚高电平
} 依旧会出现你所说的我只需要P1引脚,但是我要创建整个实例的问题。这个例子没有说面向过程的优劣,只是说你说的这个问题是个通用的问题,不是说面向对象有,面向过程就没有了 |
这个问题的最简单回答依旧还是"It depends"。为了实现某个功能,或解决某个问题,在对象的整个生命周期内,所有的字段/属性都被用到了,那就是没有浪费,实现相同的功能与面向过程是逻辑等价的,只是数据的组织形式发生了变化。如果在对象的整个生命周期内,某些字段/属性没有被用到,那就是浪费了,使用面向对象确实是会比面向过程浪费很多的内存。 struct TreeNode;
typedef struct TreeNode TreeNode;
struct TreeNode {
TreeNode *left;
TreeNode *right;
int element;
};
TreeNode *binary_tree_create();
TreeNode *binary_tree_add(TreeNode *, int element);
TreeNode *binary_tree_remove(TreeNode *, int element);
void binary_tree_destroy(TreeNode *);
TreeNode *binary_search_tree_create();
TreeNode *binary_search_tree_add(TreeNode *, int element);
TreeNode *binary_search_tree_remove(TreeNode *, int element);
void binary_search_tree_destroy(TreeNode *);
int main(int argc, char **argv) {
/* something uses create/add/remove/destroy */
} 对应的面向对象方式 struct TreeNode;
typedef struct TreeNode TreeNode;
struct TreeNode {
TreeNode *left;
TreeNode *right;
int element;
TreeNode *(*add)(TreeNode *, int element);
TreeNode *(*remove)(TreeNode *, int element);
};
static TreeNode *binary_tree_add(TreeNode *, int element);
static TreeNode *binary_tree_remove(TreeNode *, int element);
static void binary_tree_destroy(TreeNode *);
TreeNode *binary_tree_create() {
TreeNode *tree_node /* = something alloc memory */;
tree_node.add = binary_tree_add;
tree_node.remove = binary_tree_remove;
}
static TreeNode *binary_search_tree_add(TreeNode *, int element);
static TreeNode *binary_search_tree_remove(TreeNode *, int element);
static void binary_search_tree_destroy(TreeNode *);
TreeNode *binary_search_tree_create() {
TreeNode *tree_node /* = something alloc memory */;
tree_node.add = binary_search_tree_add;
tree_node.remove = binary_search_tree_remove;
}
int main(int argc, char **argv) {
/* something uses create/add/remove/destroy */
} |
------------------ 原始邮件 ------------------
发件人: "Snailclimb/JavaGuide" <notifications@github.com>;
发送时间: 2021年2月4日(星期四) 中午11:38
收件人: "Snailclimb/JavaGuide"<JavaGuide@noreply.github.com>;
抄送: "08叙事"<809935302@qq.com>;"Comment"<comment@noreply.github.com>;
主题: Re: [Snailclimb/JavaGuide] 面向过程 :面向过程性能比面向对象高?? (#431)
硬件场合下决定是否使用某语言的关键因素并不是性能因素,而是这个语言是否是实时性的,而不是使用了何种编程范式。
对于C语言和C++语言来说,所有内存资源的申请与释放都是手动进行的,所有的指令都是以程序员期望的顺序以相同的指令周期顺序执行。
对于Java语言和Golang语言等带自动垃圾回收语言来说,程序会在不适当的时机暂停线程来执行垃圾回收。对于某些任务来说可能期望在几个指令周期内接受所有外部信号并处理完成,在这种情况下暂停线程并执行垃圾回收就会导致信号的丢失。
至于说面向对象与面向过程的性能差异,我上面给出了使用C语言实现面向对象的示例了,而在Linux内核中也大量使用OOP范式来实现对硬件资源的抽象,所以说性能差异是来自于这个语言的执行机制,而不是这个语言采用的
硬件场合下决定是否使用某语言的关键因素并不是性能因素,而是这个语言是否是实时性的,而不是使用了何种编程范式。
对于C语言和C++语言来说,所有内存资源的申请与释放都是手动进行的,所有的指令都是以程序员期望的顺序以相同的指令周期顺序执行。
对于Java语言和Golang语言等带自动垃圾回收语言来说,程序会在不适当的时机暂停线程来执行垃圾回收。对于某些任务来说可能期望在几个指令周期内接受所有外部信号并处理完成,在这种情况下暂停线程并执行垃圾回收就会导致信号的丢失。
至于说面向对象与面向过程的性能差异,我上面给出了使用C语言实现面向对象的示例了,而在Linux内核中也大量使用OOP范式来实现对硬件资源的抽象,所以说性能差异是来自于这个语言的执行机制,而不是这个语言采用的编程范式。
//=========================================================
我之前两条确实刚写完就删了,因为发完之后觉得自己这半吊子把内存占用多些说得肯定不好。
因为不名原因删除了你还能看见,所以干脆向你请教,纯学习讨论目的
我之前说的话也是结合自己用c去仿写面向对象类,然后我自己使用的过程中的疑惑。但是我并不是很确定以自己的结论(所以删了)。如果你有好的解决方法,还希望告知,我给项目中的单片机专门写了类库,写的还挺全面的,实际使用的时候才发现声明结构体的时候一些我并不打算用的功能也被一起声明了。但是确确实实这样以对象的形式写,很方便,用的时候一个声明,一个构造函数就可以随便用了。我要是面向对象的搞法,做成功能函数,形参会特别长,还要我自己去定义各种专门的数据搭配功能
纯粹学习请教,如何解决这类问题呢?
这个问题的最简单回答依旧还是"It depends"。为了实现某个功能,或解决某个问题,在对象的整个生命周期内,所有的字段/属性都被用到了,那就是没有浪费,实现相同的功能与面向过程是逻辑等价的,只是数据的组织形式发生了变化。如果在对象的整个生命周期内,某些字段/属性没有被用到,那就是浪费了,使用面向对象确实是会比面向过程浪费很多的内存。至于说对象的生命周期的概念可以考虑说二叉树数据结构
struct TreeNode; typedef struct TreeNode TreeNode; struct TreeNode { TreeNode *left; TreeNode *right; int element; }; TreeNode *binary_tree_create(); TreeNode *binary_tree_add(TreeNode *, int element); TreeNode *binary_tree_remove(TreeNode *, int element); void binary_tree_destroy(TreeNode *); TreeNode *binary_search_tree_create(); TreeNode *binary_search_tree_add(TreeNode *, int element); TreeNode *binary_search_tree_remove(TreeNode *, int element); void binary_search_tree_destroy(TreeNode *); int main(int argc, char **argv) { /* something uses create/add/remove/destroy */ }
对应的面向对象方式
struct TreeNode; typedef struct TreeNode TreeNode; struct TreeNode { TreeNode *left; TreeNode *right; int element; TreeNode *(*add)(TreeNode *, int element); TreeNode *(*remove)(TreeNode *, int element); }; static TreeNode *binary_tree_add(TreeNode *, int element); static TreeNode *binary_tree_remove(TreeNode *, int element); static void binary_tree_destroy(TreeNode *); TreeNode *binary_tree_create() { TreeNode *tree_node /* = something alloc memory */; tree_node.add = binary_tree_add; tree_node.remove = binary_tree_remove; } static TreeNode *binary_search_tree_add(TreeNode *, int element); static TreeNode *binary_search_tree_remove(TreeNode *, int element); static void binary_search_tree_destroy(TreeNode *); TreeNode *binary_search_tree_create() { TreeNode *tree_node /* = something alloc memory */; tree_node.add = binary_search_tree_add; tree_node.remove = binary_search_tree_remove; } int main(int argc, char **argv) { /* something uses create/add/remove/destroy */ }
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
感谢回复,我终于明白为什么删掉了你还会看到了,居然会直接发送到邮箱里啊。
看来这个对象的生命周期中有所浪费是不可避免的,只能酌情使用了,目前使用的芯片20k的ram,比较吃紧,因为怕内存碎片化,所以我也没用动态内存。
|
区别在于编译过程的复杂度,像Java这种面相对象的编程语言中间多了一步编译字节码。 |
典型的思维误区,并且与问题无关。
这个回答还是两年前实习的时候写的。
有很多种中间代码无关的面向对象编译解决方案。比如golang和C++的封装通过object layout编译器生成对应的field
offset,多态通过vlookup查虚表,所有的对象解构都是通过编译器传递receiver到方法的第一个参数,都可以在编译器去做这些事情,与是否有字节码没有任何关系。
Java的bytecode还有LLVM
IR的本质要解决的是跨平台运行,不同的编译器前端表示和前端无关的目标代码优化。然而这些和面向对象编程范式是两个正交领域,是不该放在一起去讨论的。
OceanWild ***@***.***>于2021年12月16日 周四下午3:18写道:
… 区别在于编译过程的复杂度,像Java这种面相对象的编程语言中间多了一步编译字节码。
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#431 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AKYAXFAPKHIIXAX6I6OX2V3URGHFLANCNFSM4IKID5KQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
这里说的应该是,C是面向过程的,C++是面向对象的吧,两种语言的都是编译型语言 |
所以按我的理解是,面向过程和面向对象只是思想,不存在两者之间比较效率和性能的情况,还是得拿出场景具体情况具体分析。 |
学习了 |
Java的性能损失有两个地方: |
学习了 |
学习了 谢谢 |
学习了,学习了 |
学习了, 收获很大 |
C和C++的编译原理是一样的,不适合拿C和C++举例,java效率慢还有一个原因就是分配内存的问题,面向过程的语言大多都是自己分配内存,而面向对象的语言通常是自动帮你分配内存,这里可能就会导致分配内存不当,导致比面向过程的语言占用更多的内存,从而影响运行效率。 |
哥们,你又不给我科普,你还要恶心我一手,你是真的牛,理工科怎么有你这样的兄弟呢。
…------------------ 原始邮件 ------------------
发件人: ***@***.***>;
发送时间: 2023年3月19日(星期天) 晚上10:07
收件人: ***@***.***>;
抄送: ***@***.***>; ***@***.***>;
主题: Re: [Snailclimb/JavaGuide] 面向过程 :面向过程性能比面向对象高?? (#431)
C和C++的编译原理是一样的,不适合拿C和C++举例,java效率慢还有一个原因就是分配内存的问题,面向过程的语言大多都是自己分配内存,而面向对象的语言通常是自动帮你分配内存,这里可能就会导致分配内存不当,导致比面向过程的语言占用更多的内存,从而影响运行效率。
我是看出来了,你是完全不懂JVM,或者你只是背了一些错误过时的八股文。另外Java占用内存多也不是你说的原因。我没必要给你科普,想知道正确答案的话去看看HotSpot
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you commented.Message ID: ***@***.***>
|
我是看出来了,你是完全不懂JVM,或者你只是背了一些错误过时的八股文。
|
哥们你装什么呢,内存回收机制谁不知道似的,原因这么多,就你内存回收机制是原因?博主都已经说过了gc,我说还有别的一些原因不行吗,就你能耐呗
…------------------ 原始邮件 ------------------
发件人: ***@***.***>;
发送时间: 2023年3月19日(星期天) 晚上10:16
收件人: ***@***.***>;
抄送: ***@***.***>; ***@***.***>;
主题: Re: [Snailclimb/JavaGuide] 面向过程 :面向过程性能比面向对象高?? (#431)
我是看出来了,你是完全不懂JVM,或者你只是背了一些错误过时的八股文。
另外Java占用内存多也不是你说的原因。Java对象本身占用的空间就比C++大,不过Java的内存回收机制才是主要原因
没有任何人有义务去给你科普,给你科普那是情分,不给你科普那是本分,想知道正确答案的话去看看HotSpot
C和C++的编译原理是一样的,不适合拿C和C++举例,java效率慢还有一个原因就是分配内存的问题,面向过程的语言大多都是自己分配内存,而面向对象的语言通常是自动帮你分配内存,这里可能就会导致分配内存不当,导致比面向过程的语言占用更多的内存,从而影响运行效率。
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you commented.Message ID: ***@***.***>
|
就你这点知识量就别出来回复别人了,我都替你觉得丢脸。无知也就算了,还没教养,你是别人儿子吗?别人有义务给你科普?煞笔又不是我生的,我没必要教育它 |
牛的,你确实蛮有教养的。
…------------------ 原始邮件 ------------------
发件人: ***@***.***>;
发送时间: 2023年3月30日(星期四) 晚上9:35
收件人: ***@***.***>;
抄送: ***@***.***>; ***@***.***>;
主题: Re: [Snailclimb/JavaGuide] 面向过程 :面向过程性能比面向对象高?? (#431)
就你这点知识量就别出来回复别人了,我都替你觉得丢脸。无知也就算了,还没教养,你是别人儿子吗?别人有义务给你科普?煞笔又不是我生的,我没必要教育它
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you commented.Message ID: ***@***.***>
|
面向过程和面向对象这两个概念是语言层面的,真正比较性能的高低,我们应该去比较其底层运行机理(这里我们比较的指标是代码运行模式:全量编译?部分编译部分解释?全量解释?)是运行机理的不同才导致的其性能的差距。 |
面向过程 :面向过程性能比面向对象高。 因为类调用时需要实例化,开销比较大,比较消耗资源,所以当性能是最重要的考量因素的时候,比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发。
----》》
这个并不是根本原因,面向过程也需要分配内存,计算内存偏移量,Java性能差的主要原因并不是因为它是面向对象语言,而是Java是半编译语言,最终的执行代码并不是可以直接被CPU执行的二进制机械码。
而面向过程语言大多都是直接编译成机械码在电脑上执行,并且其它一些面向过程的脚本语言性能也并不一定比Java好。
The text was updated successfully, but these errors were encountered: