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)
16605 次点击
所在节点    程序员
134 条回复
chocotan
2019-09-23 22:40:36 +08:00
楼主你只是证明了比 Spring Boot 快而已
2kCS5c0b0ITXE5k2
2019-09-23 22:58:59 +08:00
@areless 难道不是 php 容易被腐化吗 项目一大 人一多 遇到不规范的贼乱
Vegetable
2019-09-24 00:00:04 +08:00
@gimp u8 是 uint8 吗?这地方够大吗
340244120w
2019-09-24 00:17:21 +08:00
spring 本来性能就弱,你看看调用链有多长。。。我用过的一个非 servlet 框架,有的测试是 spring 的三十多倍
jason19659
2019-09-24 01:04:12 +08:00
这点东西能测出个啥。。
KasuganoSoras
2019-09-24 02:44:35 +08:00
测试了一下 PHP 7.3.8 + Swoole 的服务器

<?php
$http = new Swoole\Http\Server("0.0.0.0", 880);
$http->on('request', function ($request, $response) {
$response->header("Content-type", "image/png");
$response->end(base64_decode("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWP4////fwAJ+wP9CNHoHgAAAABJRU5ErkJggg=="));
});
$http->start();

测试结果:0.089ms



Swoole 果然还是快,吹爆
KasuganoSoras
2019-09-24 02:45:56 +08:00
@KasuganoSoras #86 是 0.084ms,写错了
az422
2019-09-24 07:03:41 +08:00
看了下楼主的 ab 命令,应用部署和 ab 压测在同一台机器吧?这样就容易不准了。还有楼主压测机器参数是什么?然后一般来说,单个 ab 用-c1000,-n1000 这样比例搭配不合理,会导致 ab 线程调度完请求也完成了,ab 本身没预热好。建议楼主,
1.分开机器压测(局域网内)
2.ab 参数类似-c200-n10000 这样试试
3.一般不用直接-c1000,而是通过多个 ab 命令达到 1000,比如脚本
ab -c 300 xxx. &
ab -c 300 xxx. &
ab -c 400 xxx
wait
xiaotuzi
2019-09-24 08:00:02 +08:00
@qsbaq 亲测,打开了 opcache 也一样,我是本地 Windows 10,cli 执行,我用 php7.3 测的,结果是 28s+,用 PHP7.0 没有开 opcache 测出结果是 23s+,我也是 PHPer,不吹不黑,可以自己测一下。
mcfog
2019-09-24 08:09:45 +08:00
未经优化 php5 都比 java 快,正常操作
上了 laravel php7.4 比裸 php5 慢,正常操作
上 spring 慢多少我没概念

合理的优化过后,什么 php5 还是 7,java 还是 python,laravel 还是 spring 全都不是瓶颈

github 还用着 RoR 呢啥时候性能有问题了
ichubei
2019-09-24 08:25:10 +08:00
那也无法阻挡 php 的没落……
gimp
2019-09-24 08:36:19 +08:00
@Vegetable 搞错了,,放不下 =,=
wo642436249
2019-09-24 08:37:15 +08:00
照我的理解,java、go 之类的代码,是启动时候直接加载到内存中了,单凭这个就很快了,而 php 大多是跑在 fmp 中的,每次请求都重新拉起进程,这样很慢,如果把 php 加载内存中,比如结合 swoole,那破 java 也很容易
encro
2019-09-24 09:08:28 +08:00
PHP 最大问题在于没有线程(线程基本是废物大多用的是 nts 版本),只有进程,所以需要配合 swoole 之类,
但是用 swoole 写的代码即使再怎么优化,肯定不如我写了几天的 go。

效率是:单进程<多进程<多线程<协程

比如我们开发公司微信消息服务,做活动的时候一分钟会来几千个请求,收到请求后我们又去请求微信,由于微信相应通常要 60-200MS,这时候用 PHP 一个进程需要 20M 内存耗着,用 JAVA 一个线程也需要几十几百 K,但是 GO 最少只需要 2K。

意味着,一台 128G 内存的机器,PHP 也就跑几千并发,java/swoole 可以跑几万几百万并发,而 Go 可以单机几百万并发。
encro
2019-09-24 09:12:52 +08:00
@KasuganoSoras 你的那个结果报错了。。。
crazjieb
2019-09-24 09:17:21 +08:00
你在想 peach
saeed
2019-09-24 09:17:58 +08:00
java: 你没有用设计模式,要重新比! php: qnmd
raincode
2019-09-24 09:26:27 +08:00
有没有谁用 rust 测测,想知道结果
anyuhanfei
2019-09-24 09:38:14 +08:00
学算法的时候,用 python3 写一遍,用 php7.3 写一遍,基本上每个算法都比 python3 快一半
hhh798
2019-09-24 09:55:59 +08:00
@encro nodejs 能跑多少呢?

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

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

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

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

© 2021 V2EX