mrpzx001
V2EX  ›  PHP

PHP 跑 Python 比 Python 更快!

  •  1
     
  •   mrpzx001 · Dec 8, 2023 · 4686 views
    This topic created in 1064 days ago, the information mentioned may be changed or developed.

    原文

    https://github.com/swoole/phpy/blob/main/docs/benchmark.md

    压力测试

    压测脚本中创建了一个 PyDict ,分别读写 PHP 代码和 Python 代码执行 1000 万次。

    • PHP 版本:PHP 8.2.3 (cli) (built: Mar 17 2023 15:06:57) (NTS)
    • Python 版本:Python 3.11.5
    • 操作系统:Ubuntu 20.04
    • GCC 版本:gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.2)

    请注意设需要构造一个 1000 万个元素的 HashTable,需要至少 2G 以上内存空间才可以运行此测试

    PHP

    <?php
    
    $dict = new PyDict();
    const COUNT = 10000000;
    
    $n = COUNT;
    $s = microtime(true);
    while ($n--) {
        $dict['key-' . $n] = $n * 3;
    }
    echo 'dict set: ' . round(microtime(true) - $s, 6) . ' seconds' . PHP_EOL;
    
    $c = 0;
    $n = COUNT;
    $s = microtime(true);
    while ($n--) {
        $c += $dict['key-' . $n];
    }
    echo 'dict get: ' . round(microtime(true) - $s, 6) . ' seconds' . PHP_EOL;
    

    Python

    import time
    
    my_dict = {}
    COUNT = 10000000
    
    n = COUNT
    start_time = time.time()
    
    
    for i in range(n):
        my_dict["key-" + str(i)] = i * 3
    
    elapsed_time = time.time() - start_time
    
    print(f"dict set: {elapsed_time:.6f} seconds")
    
    n = COUNT
    
    total = 0
    start_time_get = time.time()
    for i in range(n):
        total += my_dict["key-" + str(i)]
    
    elapsed_time_get = time.time() - start_time_get
    
    print(f"dict get: {elapsed_time_get:.6f} seconds")
    

    PHP 数组

    <?php
    
    ini_set('memory_limit', '2G');
    $dict = [];
    const COUNT = 10000000;
    
    $n = COUNT;
    $s = microtime(true);
    while ($n--) {
        $dict['key-' . $n] = $n * 3;
    }
    echo 'array set: ' . round(microtime(true) - $s, 6) . ' seconds' . PHP_EOL;
    
    $c = 0;
    $n = COUNT;
    $s = microtime(true);
    while ($n--) {
        $c += $dict['key-' . $n];
    }
    echo 'array get: ' . round(microtime(true) - $s, 6) . ' seconds' . PHP_EOL;
    

    结果对比

    (base) htf@swoole-12:~/workspace/python-php/docs/benchmark$ php dict.php 
    dict set: 4.663758 seconds
    dict get: 3.980076 seconds
    (base) htf@swoole-12:~/workspace/python-php/docs/benchmark$ php array.php 
    array set: 1.578963 seconds
    array get: 0.831129 seconds
    (base) htf@swoole-12:~/workspace/python-php/docs/benchmark$ python dict.py 
    dict set: 5.321664 seconds
    dict get: 4.969081 seconds
    (base) htf@swoole-12:~/workspace/python-php/docs/benchmark$
    

    以 Python 测试为基准:

    脚本名称 Set Get
    dict.php 114% 125%
    array.php 337% 599%
    • phpy 以 PHP 代码写入 PyDict 的性能比原生 Python 高 14%,读取性能高 25%
    • PHP 写入 PHP Array 的性能比 Python 写入 Dict 高 237%,读取高出了近 500%

    其他

    phpy 这个项目已经进化到可以调用任何 python 内置常量、函数、模块,包括 print 、compile 、eval 、exec 等等,也就是说你完全可以用 php 的语法来写 python ,比如

    https://docs.python.org/zh-cn/3/library/ast.html#module-ast
    示例代码:print(ast.dump(ast.parse('x = 1'), indent=4))
    
    php 写法:
    $py = PyCore::import('builtins');
    $ast = PyCore::import('ast');
    $py->print($ast->dump($ast->parse('x = 1'), indent: 4));
    

    以上只是写着玩,phpy 的初衷是用 python 来弥补 php 生态上的不足,现在你可以用 php 来跑大模型了

    13 replies  •  2023-12-09 13:04:19 +08:00
    ersic
    ersic
    Dec 8, 2023
    1
    可是今天韩天峰刚说了,损耗在 50%左右
    mrpzx001
    mrpzx001
    OP
    Dec 8, 2023
    2
    @ersic 他昨天测试的时候用的是 debug 版的 php ,性能当然差了
    aogg
    aogg
    Dec 8, 2023
    3
    能不能用 python 的库,比如 gui 界面之类的,还有大模型的类库
    aogg
    aogg
    Dec 8, 2023
    4
    不能支持多线程的原理是什么
    tf2
    tf2
    Dec 8, 2023❤️1
    5
    凡事编程语言跑分,python 一看到 for 就直接宣布比赛结束了。
    tf2
    tf2
    Dec 8, 2023
    6
    另外
    my_dict["key-" + str(i)] = i * 3

    改成

    my_dict["key-%s"% i] = i * 3

    我这里会从 5.6 秒变 4.6 秒。
    tf2
    tf2
    Dec 8, 2023
    7
    换成 my_dict[b"key-%d"% i] = i * 3 变成 3.6 秒。

    结论:字符串是个体力活。
    mrpzx001
    mrpzx001
    OP
    Dec 8, 2023
    8
    @aogg 能,轻轻松松跑起来 chatglm3 ,gui 更不在话下了,可以看 example
    mrpzx001
    mrpzx001
    OP
    Dec 8, 2023
    9
    @aogg 不是不能,大佬没空而已,说不定哪天兴致来了就支持了
    NoOneNoBody
    NoOneNoBody
    Dec 8, 2023
    10
    试试
    my_dict = {f"key-{i}": i*3 for i in range(n)}
    ...
    total = sum(my_dict.values())
    我没环境测试

    最想不通在无需过滤的情况下,求 total 为什么要跑个 for 累加器,抓着痛处打?
    encro
    encro
    Dec 8, 2023
    11
    没达到一个数量级差别的优化,意义都不大。。。。
    lisxour
    lisxour
    Dec 8, 2023
    12
    numpy 这类的库不是有专门的优化嘛,这能打得过?
    crackidz
    crackidz
    Dec 9, 2023
    13
    这不是比了个寂寞...一到 Python 代码里面速度不就一样了
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2094 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 54ms · UTC 02:46 · PVG 10:46 · LAX 18:46 · JFK 21:46
    ♥ Do have faith in what you're doing.