起因是与同事的一次争执(个人单方面挑起)。
简单说下现场情况:
PHP 开发,Laravel 框架。
第一件事:
一同事不满我于每次使用 Redis 都要先 Redis::connection();
他认为这次 connection() 会单独开一个 Redis 链接,性能损耗大。
而我认为直接使用魔术方法没有代码提示且 IDE 会标黄,看着不爽~
最后给他看 Laravel 源码,证明调用魔术方法本身也是先 connection() 然后调用方法。
而且证明 connection() 内并不一定会新创建链接。
事实上,Model 我也是先 query() 后 where()。
(这个我专门查过 Model 的源代码,都一样的,但 Redis 确实没查过。)
// 我的代码
Redis::connection()->pipeline();
// 他提议的
Redis::pipeline();
// 实际上 Redis::pipeline(); 的实现方法是
$this->connection()->{$method}(...$parameters);
第二件事:
我使用观察者来在订单 status 变更时记录到日志。
而他认为每次修改数据库都会触发观察者,性能损耗大。
而我主张,为了减轻服务器损耗,而提高人员的开发成本,得不偿失。
我的结论:
既然使用框架了,那为何不充分利用他便捷的特性呢?
追求极致的性能为何还要使用笨重的框架,直接原生手写代码就好了呀。
不知道是不是我的主张是错误的,求打醒。
========
不过我的脾气是真不好,当场就开怼了,要改,要改...
1
66450146 2019-07-18 20:46:33 +08:00
性能损耗大不大是要 profile 出来的,不是瓶颈的地方没有优化的必要
|
2
kzzhr 2019-07-18 20:46:37 +08:00 via iPhone
好耐心啊,直接让他压一下,看看他的写法提了有没有半个 qps 就行了
|
3
nine 2019-07-18 20:49:24 +08:00
(如果你写过要求高性能的程序就会知道)你同事是对的。
|
4
leeyuzhe 2019-07-18 20:53:29 +08:00 via Android
不服就压一下试试嘛,肯定是 qps 说了算
|
5
leekafai 2019-07-18 22:11:27 +08:00 via Android
好的程序员负责在瓶颈前实现需求,好的架构师负责将瓶颈提高,我觉得谁都没错
|
6
niubee1 2019-07-18 22:13:46 +08:00 2
提前优化是原罪,sin, 要吊起来烧死
|
7
Cbdy 2019-07-18 22:15:29 +08:00 via Android
优化考猜的吗?
|
8
rrfeng 2019-07-18 22:17:21 +08:00 via Android
pho 每个请求起进程的方式这里确实没必要优化。
如果是 fpm 常驻进程就有区别。 |
9
iEverX 2019-07-18 22:18:16 +08:00
不针对楼主的几个问题,因为不清楚其中的性能开销到底是多少。
> 而我主张,为了减轻服务器损耗,而提高人员的开发成本,得不偿失。 ======= 这一点不一定一直成立,服务器成本不低的。特别是由于性能不行,不得已加多台机器,就会更高了。 > 追求极致的性能为何还要使用笨重的框架,直接原生手写代码就好了呀。 ======= 就如上面几楼所说,性能评估肯定是压测压出来的。不用 php,不过 spring boot 服务,压测从从来瓶颈不在 spring boot。 |
10
chenqh 2019-07-18 22:25:34 +08:00 via Android 2
用 laravel 还讲究那么多?
|
11
mamahaha 2019-07-18 22:32:47 +08:00 2
过去在工厂都是先把东西做出来,先投入市场。如果口碑好批量上来了,再考虑降本增效,利润回报的大头都会从节降成本里产生。
如果研发阶段就降本增效,那只有两种情况,一种是系列产品换个马甲,还有一种是我也不知道。 |
12
Linxing 2019-07-19 00:21:54 +08:00
效率的基础上 提高性能 但是如果有大量的用户了 还是性能优先
|
13
ben1024 2019-07-19 00:36:47 +08:00
开发速度和开发者体验在没有遇到性能瓶颈前是最重要的
|
14
jinliming2 2019-07-19 01:01:41 +08:00 via iPhone
过早优化不好,但顺手优化还是赞成的……
勿以优化小而不为,毕竟积少成多。随手养成良好的习惯,实现同样效果的代码,坚持使用最优的,即便是多写几个字母。 但说了是随手优化,所以没有必要为了写法的优劣而吵架!!! 但如果对一段代码的优化明显占用了工时,那就没必要了,这种优化还是放到最后需要优化的时候,测测瓶颈再来考虑是否继续吧…… 关于框架,我觉得不能过于依赖。框架是用来加速开发的,如果同样的功能原生代码可以快速实现,没有必要专门用框架封装的。特别是大型框架,能够用来帮你组织项目结构,帮你组织整个工程的逻辑结构,这就足够了,其他封装的方法都只是“语法糖”。这些封装的方法有的为了适应不同的执行环境而写了大量的分支判断,这个时候,自己针对项目用原生代码实现一个量身定做的封装岂不更好? |
15
akira 2019-07-19 02:33:30 +08:00
你是要被打,我们是连数据库自带的触发器都不建议使用的,何况是这种触发器.
|
16
opengps 2019-07-19 06:59:00 +08:00 via Android
压测说明问题
|
17
palfortime 2019-07-19 07:47:31 +08:00 via Android
我只知道不好的框架使用习惯会被慢慢 copy/paste 到整个项目。如,service 层进门就打个 @Transactional,管它逻辑复不复杂,有没有外部调用;如,play 框架中所有函数返回都是 Promise<String>,map/recover 是什么,没有看过。
有些行为不加以纠正,那就希望项目涨量时,维护人不是你。 |
18
Fule 2019-07-19 08:47:04 +08:00 1
我觉得这个问题得两面看。如果是热点路径,那么每一点性能优化都是值得的,非热点路径,还是以便利性和可读性为主吧。不过总体来说,注重性能是一个好习惯。当然如果你们有压测的方法,那就用数据说话。
最后,这种事情没有绝对对错之分,也算是技术和思维切磋,不要太情绪化了。 |
19
Kilerd 2019-07-19 08:56:27 +08:00 2
没进来之前以为是吐槽 rust 的
|
20
jonsun30 2019-07-19 09:04:44 +08:00
参考 Uinx 哲学
|
21
leo108 2019-07-19 09:04:47 +08:00
抛开业务谈优化都是耍流氓,抛开项目阶段谈优化更是耍流氓。
|
22
lance6716 2019-07-19 09:28:28 +08:00 via Android 1
我比编译器聪明
我战胜了标准库 我能管理好内存 |
23
misaka19000 2019-07-19 09:31:03 +08:00
原来写 PHP 是不需要考虑性能的,难怪 PHP 是世界上最好的语言
|
24
wweir 2019-07-19 09:34:59 +08:00 via Android 1
说实话,挺烦那种自身半瓶水,还天天提优化的人。
性能优化有自己的完整方法论,远不是那些道听途说的优化建议能解决的。 PS: 自己时常会做些过早优化的事,这是病,得治 |
25
gwybiaim 2019-07-19 09:38:54 +08:00
@lance6716 对对对,有人总认为自己比框架牛逼,比标准库性能高,比编译器更懂代码执行。哎,费心巴力写了一堆,可读性降了不少,性能还不见得好。关键等底层优化的时候,这堆自己写的逻辑不能方便的享受到底层优化带来的性能提升。
|
26
crackhopper 2019-07-19 09:39:03 +08:00
1. 不要太较真,他较真,带来的改变如果不太复杂,就接受就好了;要不然浪费精力。
2. 正是因为你们俩都没错,又都太较真,所以才会矛盾。 3. 提前优化是错误的,便捷性重要;能顺手优化掉的,优化掉也是正确的,毕竟也不会有太大麻烦,还养成个好习惯; 4. 错误的有:性能无法支撑业务的情况下,仍然快速撸业务(应该做 profile,进行一下优化,或者横向扩展);性能足以支撑业务的,花大量精力去优化(用一些非常识性高级优化技术,比如 SIMD,预测,unwind 之类的)。 |
27
jsjscool 2019-07-19 09:45:34 +08:00
// 他提议的
Redis::pipeline(); 可能比你的方案要好些。 一是封装之后更容易扩展,比如连接之后打个日志,他只改一行,你可能要改一天。 二是 ActiveRecord 的设计哲学就是深度封装,能封装的都封装起,让上层知道的越少越好,你甚至都不需要知道用的 Redis 还是 MySQL,connection()就更不需要知道(只是猜测你们用了 ActiveRecord )。 至于性能,性能瓶颈真的是可遇不可求,遇到了至少可以吹 5 年。 |
28
ChoateYao 2019-07-19 09:49:56 +08:00
第二个问题确实是你的问题,应该是要在会修改订单状态的地方监听事件,而不是全局监听,全局监听虽然方便了你的开发,但是后期带来的问题苦不堪言。
|
29
lhx2008 2019-07-19 09:54:31 +08:00 via Android
用 laravel 等 PHP 框架还讲什么性能。。dump 调用栈,每个请求就执行几万行内置代码,redis 也做不了连接池。有啥区别。
|
30
lhx2008 2019-07-19 09:57:12 +08:00 via Android
不过,laravel 的数据库监听确实不好用,后续有新代码的时候,处处都要考虑旧的监听器。正确做法应该是手动发消息,不要啥都自动
|
31
1239305697 2019-07-19 10:55:59 +08:00
我也不用 query() ...
|
32
nekoyaki 2019-07-19 17:11:04 +08:00
是这样,优化有成本也有收益,我建议是你们根据你们的场景,平心静气求同存异,来合理评估一下高性能和快开发的好处和坏处,以后达成一致了大伙都好干活。
而且这个成本和收益也不是一直不变的,如果前头有一个耗时 30ms 且无法优化掉的操作,你把这个耗时 3 毫秒的操作优化成了 1ms,看起来是优化了三倍,但里外里的效用其实非常低。如果还让代码写起来更复杂了,那可能就不是一个很有必要的操作。 但如果你是把这个每天调十万次的操作从 30ms 优化到了 10ms,里外里就能省很多时间,省出来的时间就是服务器和人的钱。 |