27

用 Python 重写了 C 语言实现的 Solaris 命令,代码减少 90% 而性能提升 17 倍

 4 years ago
source link: https://www.infoq.cn/article/DuI2camvUuqSw8raQA3x
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

/usr/bin/listusers 命令中,我修复了一个内存分配的错误,这个错误在该命令转为 64 位时会引起一些问题。在修复这个错误之后,我决定研究一下这段古老的 C 代码是否能在转换为 Python 实现后得到一些改进。

V7zuayA.png!web

这段 C 代码大约有 800 行,但从 1988 年后就基本没有动过了,在编写这段代码的那个年代,用户数还相当少,很有可能用户信息是在 /etc/passwd 这个本地文件中或者在小型的 NIS 服务器上。

经过一番研究后,我发现 listusers 的算法基本上就是一些简单的集合操作。listusers 命令不带参数,它只是把排好序的用户列表输出到域名服务里,命令后的 -l 和 -g 选项用来过滤用户和组所在的列表。

我用 Python3 重写了 listusers,代码行数几乎只有原来代码的 1/10——由于 Python 本身包含了集合操作,而 C 版本代码自己使用链表实现了集合操作。

但是 Python 应该会更慢一些吗?结果证明不是。实际上,在我的数据库里(数据库里包含超过 10 万的用户)测试,它反而快了 17 倍。而且,我还肯定,当 Python 版本知道命令使用了 -l 和 -g 选项做过滤时,它不会把整个域名服务内容同时放进内存里。

改成 Python 后,我发现之前一个长期存在的 bug 变得很容易修复,即 listusers 不能正确地扩展嵌套组的问题。之前用 C 代码编写时,并不存在嵌套组这个概念,但是,使用 LDAP,嵌套组就可以实现了。

改成 Python 后,我还发现这 100 行 Python3 版本的代码将会很容易向前维护——尽管我希望 listusers 不需要再有什么更新,因为它的原有代码都已历经了好几十年!

原文链接:

https://blogs.oracle.com/solaris/reimplementing-a-solaris-in-python-gained-17x-performance-improvement-from-c


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK