php7 怎么比 Java 还快?

2019-09-23 11:22:47 +08:00
 zjsxwc

有点反认知,分别用 PHP 与 Java Spring Boot 写了个返回 1 个像素点图片的接口,结果 php 比 java 快。

代码

PHP 代码

<?php
//xpng.php

header("Content-type: image/png");

echo base64_decode("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWP4////fwAJ+wP9CNHoHgAAAABJRU5ErkJggg==");

Java 代码

//XController.java

package com.abtest;

import java.util.Base64;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class XController {
    @RequestMapping("/x.png")
    public ResponseEntity<byte[]> xpng() {
        String onepointpngBase64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWP4////fwAJ+wP9CNHoHgAAAABJRU5ErkJggg==";
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.set("Content-type", "image/png");
        byte[] decodedValue = Base64.getDecoder().decode(onepointpngBase64);
        return new ResponseEntity<byte[]>(decodedValue, responseHeaders, HttpStatus.OK);
    }
}

开始测试

Server 分别 SpringBoot Jar 包自带的 Apache Tomcat/9.0.24

PHP 就是 PHP 7.0.33-0+deb9u1 (cli) 自带的低性能调试用 server (使用php -S localhost:7767 -t .运行)

AB 结果反直觉,PHP 居然比 Java 快

PHP 结果耗时 0.125 秒
$ ab -n 1000 -c 1000 "http://localhost:7767/xpng.php"
This is ApacheBench, Version 2.3 <$Revision: 1757674 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:       
Server Hostname:        localhost
Server Port:            7767

Document Path:          /xpng.php
Document Length:        70 bytes

Concurrency Level:      1000
Time taken for tests:   0.125 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      190000 bytes
HTML transferred:       70000 bytes
Requests per second:    8011.99 [#/sec] (mean)
Time per request:       124.813 [ms] (mean)
Time per request:       0.125 [ms] (mean, across all concurrent requests)
Transfer rate:          1486.60 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    6   5.5      8      14
Processing:     5   22  20.1     13      69
Waiting:        4   22  20.2     12      69
Total:          8   29  21.3     19      71

Percentage of the requests served within a certain time (ms)
  50%     19
  66%     24
  75%     37
  80%     62
  90%     68
  95%     70
  98%     70
  99%     70
 100%     71 (longest request)
Java 结果耗时 0.498 秒
$ ab -n 1000 -c 1000 "http://localhost:8080/x.png"
This is ApacheBench, Version 2.3 <$Revision: 1757674 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:       
Server Hostname:        localhost
Server Port:            8080

Document Path:          /x.png
Document Length:        70 bytes

Concurrency Level:      1000
Time taken for tests:   0.498 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      188000 bytes
HTML transferred:       70000 bytes
Requests per second:    2007.85 [#/sec] (mean)
Time per request:       498.046 [ms] (mean)
Time per request:       0.498 [ms] (mean, across all concurrent requests)
Transfer rate:          368.63 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   3.2      0      11
Processing:     5   73  63.3     48     237
Waiting:        3   64  56.7     41     194
Total:          5   74  66.0     48     247

Percentage of the requests served within a certain time (ms)
  50%     48
  66%     63
  75%     76
  80%     88
  90%    216
  95%    225
  98%    229
  99%    234
 100%    247 (longest request)
16543 次点击
所在节点    程序员
134 条回复
ben1024
2019-09-23 16:35:44 +08:00
不知 php7.4 + swoole 效果如何
qq316107934
2019-09-23 16:39:52 +08:00
别的结果看起来很合理,为什么 Golang 这么慢?
Vegetable
2019-09-23 16:44:57 +08:00
@qq316107934 试了一下,的确就是这么慢,我也很好奇...
stabc
2019-09-23 16:49:25 +08:00
PHP7 有脚本缓存吧,也就是说,段时间内大量执行同一代码,相当于在测试 C 语言的速度。
icexin
2019-09-23 16:55:10 +08:00
golang 慢是因为它里面的 int 在 64 位环境下是 64 位的,把其他语言换成 int64 时间就很接近了
raincode
2019-09-23 16:56:48 +08:00
nodejs 呢?
cjh1095358798
2019-09-23 16:58:13 +08:00
php 还是牛逼,js 也可以
iPhoneXI
2019-09-23 16:58:35 +08:00
@Hanggi Python 加个 uvloop 就快了
xfriday
2019-09-23 17:04:19 +08:00
@icexin 确实有这个原因,golang 换成 int32,时间可以降低一半,我的 mbp 是 5.29s ,还是和 java 有点差距,js 为啥那么牛批?-_-b
xnode
2019-09-23 17:05:36 +08:00
php 的效率并不低,php 令人诟病的是 fpm 的模式的效率 以及不规范的开发模式 .换句话说 php 的天花板低
photon006
2019-09-23 17:06:04 +08:00
我测了 node.js ,v10.13.0 长期支持版,代码:
```
'use strict';
const http = require('http');

http.createServer(function (req, res) {
let data = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWP4////fwAJ+wP9CNHoHgAAAABJRU5ErkJggg==';
// console.time('耗时:')
let buff = Buffer.from(data, 'base64');
let text = buff.toString('ascii');
// console.timeEnd('耗时:')
res.writeHead(200, {'Content-type': 'image/png'});
res.write('asdfasd');
res.end();
}).listen(8080);
```


ubuntu 18.04 安装 AB:
sudo apt install apache2-utils

测试代码:ab -n 1000 -c 1000 "http://localhost:8080/"

测出结果程序启动第一次:Time per request: 0.350 [ms] (mean, across all concurrent requests)
再测,维持在 0.160ms 左右


这个跟 cpu 有关吧
xfriday
2019-09-23 17:07:07 +08:00
看来 js (浏览器端)除了没法多线程,性能已经优化到 java 级别了
Vegetable
2019-09-23 17:08:08 +08:00
@xfriday 因为 js 也是 jit 吧,pypy3 我这里也可以达到六七秒的样子。
我这里 go1.13 是 12s,pypy 七点几。java 换成 long 是 11s 多,go 换 int32 是 7.5 左右,没降到一半,大概还有别的原因。
zjsxwc
2019-09-23 17:10:58 +08:00
@iminto

我用 golang,9000 并发时可以稳定在 0.35 秒左右
我用 c++写,9000 并发时可以在 0.5 秒左右 ( https://github.com/zjsxwc/xpng-test/blob/master/src/controller/MyController.hpp#L149
都是在一个数量级,差别不大
tanranran
2019-09-23 17:12:58 +08:00
@xfriday #32 #32 JS 现在可以通过 worker 实现多线程
photon006
2019-09-23 17:13:07 +08:00
@xfriday 浏览器也可以用多线程,公司目前有个上传文件功能,做了大文件、批量上传、进度条、断点续传功能,但要保证文件 100%可靠,后台我用 node 异步计算 md5,客户端我打算让前端同学用 web worker 实现。
stevenhawking
2019-09-23 17:16:23 +08:00
原来是友军
xfriday
2019-09-23 17:18:32 +08:00
@tanranran @photon006 是的,通过 web worker,js 也可以玩多线程了
keepeye
2019-09-23 17:19:35 +08:00
golang int32 效率提升 40% 禁用 gc 没有啥提升 但还是比较慢 好奇原因
qsbaq
2019-09-23 17:22:39 +08:00
楼猪,你有没有把 PHP 的 OPCACHE 打开?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/603272

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX