V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  lesismal  ›  全部回复第 35 页 / 共 63 页
回复总数  1256
1 ... 31  32  33  34  35  36  37  38  39  40 ... 63  
2023-02-15 15:54:02 +08:00
回复了 aapeli 创建的主题 Go 编程语言 有一个 Golang 泛型的问题咨询
@Nazz #29
> 泛型本来就不能提高性能啊, 只是减少重复工作. 一个 Max 肯定比 MaxInt64, MaxInt32...优雅

你这里所述的是基础类型,我 #17 所说的 "泛型适合运算符重载之类的基础类型场景" 就是支持这样做的,这种场景我对使用泛型没有异议。

"泛型本来就不能提高性能啊" 是不正确的,只是 go 目前的泛型实现方案对自定义结构体类型没带来性能提升,但是其他一些语言是做到了的。我觉得可能是由于 go 自带 runtime 面临着更多复杂性,所以目前阶段没有支持这种优化,或许随着 go 未来版本编译器的优化也能带来这些提升。

泛型"能够"性能提升的场景主要是自定义的结构体类型相关的。
你可以先找些资料来研究下,比如面向对象多态的函数表,比如 c++模板静多态,我前面提到的 "泛型会让你的 Go 代码运行变慢",帖子里有讲比我更专业更深入的,引用一段落:
"从历史上看,C++、D 乃至 Rust 等系统语言一直采用单态化方法实现泛型。造成这一现实的原因很多,但总体来说就是想用更长的编译时间来换取结果代码的性能提升,并且只要我们能提前把泛型代码中的类型占位符替换成最终类型、再进行编译,就可以极大优化编译流程的性能表现。装箱方法就做不到这一点。另外,我们还可以对函数调用进行去虚拟化以回避 vtable ,甚至使用内联代码实现进一步优化。"

甚至不需要去研究这些,你可以站在编译器和运行时的角度自行想象一下比如:interfaceA 的一个实例在进行方法调用时,如何通过这个实例的指针实现方法调用?
首先你得知道这个实例的类型,否则A类型调用到B类型的方法上去就乱套了,go 的指针是胖指针,指向的内容一部分是类型元信息,一部分是指向值本身。要实现实例化调用,首先要通过这个 interfaceA 实例的指针去解引用取得类型信息、找到函数表,然后再把值和函数结合起来使用。这是由 runtime 来处理的,运行时才能搞定。
而静多态 /单态化,比如 c++模板,是编译期就生成了对应类型的代码,与上面说的 interfaceA 由运行时处理对比一下,静多态 /单态化可以把 runtime 先确定类型信息这一步省掉,虽然只是一些简单的指针操作,但量大积累起来,性能差距就拉开了。
2023-02-15 13:28:02 +08:00
回复了 aapeli 创建的主题 Go 编程语言 有一个 Golang 泛型的问题咨询
@lesismal #27 更正
我觉得这样说不太正确。接口与面向对象是不同的:
1. 面向对象是自顶向下的约束,非父类本身或者子孙类无法作为祖辈参数的实例入参传入;
2. 接口没有强制的向下约束,而是以更自由松散的方式、按需定以按劳分配,完全可以根据需求、抽取需要实现的方法集合作为一个单独的接口定以去作为其他公共形式的使用。可能是由于大家平时一些自定义类型需要去实现标准库已经定义了的接口,才会有这种被约束的错觉。
2023-02-15 13:26:10 +08:00
回复了 aapeli 创建的主题 Go 编程语言 有一个 Golang 泛型的问题咨询
@GeruzoniAnsasu #25
> 接口有个很大的问题是不能只实现部分

我觉得这样说不太正确。接口与面向对象是不同的:
1. 面向对象是自顶向下的约束,非父类本身或者子孙类无法作为祖辈参数的实力传入;
2. 接口没有向下约束,而是以更自由松散的方式、按需定以按劳分配,完全可以根据需求、抽取需要实现的方法集合作为一个单独的接口定以去作为其他公共形式的使用。可能是由于大家平时一些自定义类型需要去实现标准库已经定义了的接口,才会有这种被约束的错觉。

比如 struct A 实现了 M() X() Y(), struct B 实现了 N() X() Y(),泛型需求是需要在泛型方法里调用 X() Y()。可以定义一个 interface XY{ X() Y() } 抽取他们公共的部分,以接口的方式替代泛型,当然,这个单独的定以是一点额外的成本,但并不算复杂。

标准库的很多接口定义,是根据多年的工程实践总结出来的一些通用抽象,这些是属于基础设施、系统编程范畴的。
而相比于标准库、我们基于其上构建的,基础库也好、业务需求也好,更多的是基于自己需要来进行定义,这些自定义的约束来自自己的设计、可以灵活处理,并不需要太被标准库约束。
2023-02-15 13:10:15 +08:00
回复了 aapeli 创建的主题 Go 编程语言 有一个 Golang 泛型的问题咨询
@Nazz

> 泛型声明里面限定了 int, float 之后自然可以做加减乘除, 更复杂的操作即使有重载操作符也不够用, 我认为泛型主要是给写库的人使用的

泛型也好,接口也好,或者其他语言的面向对象多态,以及 c++的模板静多态(编译期为每种实际类型生成代码性能更好),所有这些都是为了系统设计时的公共操作抽象做语法基础。
所以不管是泛型还是接口,都是需要这些“同类”obj 具有一组相同的操作(运算符或者方法)。

就 go 而言,除去基础类型能支持运算符,对于自定义类型的 struct ,只能通过方法来实现相同操作,而对于多个类型的同名同形式方法,以接口的方式作为其他方法的参数要比以泛型的方式来定义其他方法更简洁明了,而且版本兼容性也更好。

另外就是性能,截至目前,自定义类型的泛型性能应该是不够好的,可以搜一下 “泛型会让你的 Go 代码运行变慢” 这个帖子看看,或者其他关于范型性能的帖子。
所以对于写库的人来说,如果出于性能考虑,目前的泛型也是应该放弃,连接口都不要用而是把接口访问自己元类型这层中转的指针操作也省去、自己手撸不同类型的实现才是最好的选择,而对于写库的作者,其实用不用范型节省不了太多工作量,毕竟基础设施的领域不像 CURD 那样经常搞很多需求。
当然,如果后续版本的编译器能像 c++模板那样以静多态的方式来提高性能是最好了,然后如果性能敏感的场景来替代接口的方式,也可以不用手撸多种类型的实现替代泛型了

> 不熟悉模板元编程,但模仿 cpp 的话无疑会让 go 变复杂许多

并不是模仿 c++,而是目前 go 的泛型除去基础类型范畴,既没有性能提升也没有使代码更加优雅简洁。反倒是很多人为了泛型而泛型、本来不需要泛型的地方都想用泛型,反倒把 go 搞复杂了。
2023-02-15 11:26:54 +08:00
回复了 aapeli 创建的主题 Go 编程语言 有一个 Golang 泛型的问题咨询
@Nazz #18
对比下 c++,因为 c++有运算符重载,所以模板这种泛型里类也可以直接加减乘除这些运算符、因此不需要使用方法如 a.Sum(b)。而 go 里没有运算符重载,很多算法数据结构里即使使用泛型,仍然需要以接口的形式由 struct 实现接口,然后用 a.Sum(b)之类的函数调用方式来处理。显而易见,既然这种地方已经使用接口方法了,这里的泛型就是多余的了。
多数时候是在使用基础类型为主的地方,使用泛型可以节约代码、不用为每种类型都去实现一个 /一组方法或者单个方法内再做类型转换。而本来接口、切面就能做的地方,泛型是画蛇添足。

所以有了我在#17 的观点。

自从支持了泛型以后,不少人为了用泛型而用泛型,让 go 代码变得更丑陋了,很不希望看到一些大厂“架构师”又来污染放毒,因为太多小白会跟风,最终劣币驱逐良币。
2023-02-14 22:57:00 +08:00
回复了 aapeli 创建的主题 Go 编程语言 有一个 Golang 泛型的问题咨询
@Nazz
如果入参不是对应具体 interface{...}类型也是编译期就失败的。

@aapeli
个人感受是:go 的泛型适合运算符重载之类的基础类型场景,自定义类型通常用 interface{...}或者切面更加简洁清晰、硬要为了用泛型而去用泛型,可能会让代码更难看。

再根据我浅薄的 go 泛型使用经验(不超过 10 分钟),能用接口、切面解决的问题不要用泛型就是最优解。
——不一定对,仅供各位参考
怀念那些用牛皮纸包书皮的青春岁月
2023-02-07 15:53:14 +08:00
回复了 Nazz 创建的主题 程序员 求教,个人开源项目如何才能快速积累 star
@Nazz 来试试我这个,也支持 http ,github.com/lesismal/arpc
2023-02-07 14:52:42 +08:00
回复了 Nazz 创建的主题 程序员 求教,个人开源项目如何才能快速积累 star
@bitkuang8 一看当前 599 ,连项目是做啥都没看我就点了,图个 600 的喜庆
你们有没有也发现,OP 的头像跟 OP 本人确实挺搭的
2023-02-01 20:35:14 +08:00
回复了 DigitalHarace 创建的主题 程序员 不会说话的人如何学习酒桌敬酒文化
00 后整治职场,这里只建议 00 后不要学,否则就是四九国军。

PS ,标题第一眼看成了 “不会说人话的。。。”
让我们这些 7080 后的人情何以堪
好嘛,35 岁还不够早,感觉以后大厂要搞 32 岁毕业了
2023-01-19 14:32:57 +08:00
回复了 never2023 创建的主题 随想 父母也是势力的,看房 车 工资高不高,不看工种
@qeqv 这几年 AI 写作发展太快了,以后类似的会越來越多
2023-01-08 01:05:26 +08:00
回复了 never2023 创建的主题 随想 父母也是势力的,看房 车 工资高不高,不看工种
OP 的行文,不像是人,猜测是 AI 在进行机器学习吧。
2023-01-04 16:54:40 +08:00
回复了 fxjson 创建的主题 Go 编程语言 go 每一个数据库库使用起来都不太方便,有木有
其他那些功能太多了,涉及到的细节处理也多。
我的库主要就是在 std 基础上封装了反射的部分,rawsql 能用的部分依旧能用,封装过的 sqlw.DB 提供了一点便捷的方法,让用户减轻结构体与传参、结果绑定部分的工作量,如果熟悉标准库的 rawsql ,不需要去学习其他那些库的基础只是、看下例子就懂了
话说,我就是因为其他库太复杂了,学不懂 /动,所以一直使用 rawsql ,后来写了这个,省力多了
2023-01-04 16:45:41 +08:00
回复了 fxjson 创建的主题 Go 编程语言 go 每一个数据库库使用起来都不太方便,有木有
试试我这个呀:
https://github.com/lesismal/sqlw

我也喜欢原生,但是 sqlx 那些也并不好用,所以按照自己喜欢的方式撸了个

旧帖:
https://www.v2ex.com/t/861739

也欢迎关注我的其他库:
https://www.v2ex.com/t/794435#reply4
2022-12-27 21:58:14 +08:00
回复了 13936 创建的主题 程序员 你们有过想要舔屏的冲动吗?
什么壁纸这么逼真?
2022-11-16 12:01:30 +08:00
回复了 wencan 创建的主题 Go 编程语言 实现了一套基于 lockfree 的并发安全的数据结构
> 只 add 的话,bag 会有几倍的优势

要不先试试弄个并发消息队列试试能不能比 chan 性能提升?我不太确定,因为还要有唤醒机制,用 cond 的话,意义还是不太大,可能优势主要是代码比 chan 的逻辑简单

因为数据存起来主要就是为了拿出来用,所以只 add 的场景,我暂时还想不出来

开始写 go 后我一直忽略了 go 的无锁相关,觉得没用,闲了我也学习研究下你的实现。

> 额外问下,nbio 是不是牛逼 io 的意思?

主要是 non-blocking 的意思,早期版本 readme 里还真加过牛逼的意思,后来删掉了:
https://github.com/lesismal/nbio/commit/c5122cc157bf098a4354eb75773c672233fb41de
性能应该是不输于其他 poller 框架的( evio/easygo/gnet/gev ):
https://github.com/lesismal/go-net-benchmark/issues/1

但是功能、可定制扩展空间,比他们丰富太多了,所以也对得起牛逼这俩字了。

我还想支持 HTTP2.0/3.0 ,但是工程量有点大、时间和体力吃不消,如果有兴趣,业余时间可以一起玩玩
2022-11-16 11:07:24 +08:00
回复了 wencan 创建的主题 Go 编程语言 实现了一套基于 lockfree 的并发安全的数据结构
> slice 的 Load 问题,如果是纯 Load ,Load 时没有 Append 和 Update ,确实不需要加锁。
> 欢迎提供能发挥场景多的无锁数据结构需求。

我以前接触过的、自己能想到的并发无锁优化性能的场景暂时只有一个,无锁队列做生产者消费者。比如多 IO 线程把事件丢到队列里,每个队列单线程 eventloop 消费。
但这种生产消费模型,也是与锁、同步(包括唤醒)机制比如信号量条件量。
通常的原子性(一组操作)场景都是不能简单到只使用无锁数据结构实现的,而 go 的 chan 里已经是自带了同步唤醒机制,入队出队也都是它自带流程里处理了的,所以多数时候,直接使用 chan 也就够用了。

我在自己网络框架中,对每个 connection 事件的有序执行设计用到了个执行队列,但是是直接用的[]T+Mutex ,因为对于单个 connection ,并发竞争的概率极低,Lock/Unlock 的开销就也只是简单的原子操作,所以也没必要引入无锁数据结构,而且是需要先判断是否队首再看要不要 pop 的多步骤,简单的无锁 get/set 并不能满足需求:
https://github.com/lesismal/nbio/blob/master/conn.go#L82

无竞争时 Mutex 的开销:
https://github.com/golang/go/blob/master/src/sync/mutex.go#L83
1 ... 31  32  33  34  35  36  37  38  39  40 ... 63  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5472 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 27ms · UTC 07:03 · PVG 15:03 · LAX 23:03 · JFK 02:03
Developed with CodeLauncher
♥ Do have faith in what you're doing.