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)
16505 次点击
所在节点    程序员
134 条回复
metinfo
2019-09-23 11:58:51 +08:00
PHP7 确实效率提高了不少
ccalywm
2019-09-23 11:59:43 +08:00
PHP 是世界上最好的语言
zgqq
2019-09-23 12:10:40 +08:00
你用原生的 php 和 封装了 n 层的 spring boot 比。。。
srx1982
2019-09-23 12:11:09 +08:00
别用 spring 试试
guyeu
2019-09-23 12:23:56 +08:00
不太了解 PHP,java 你可以把这个返回值抽出一个常量,应该会快很多。
如果测试的对象是 Base64 的 decode,用循环试试。
zjsxwc
2019-09-23 12:35:52 +08:00
@srx1982
@zgqq


我用 servlet 写了,跑在 Tomcat/9.0.22 上,耗时 0.259 秒,还是比 php 慢,要知道 php7 用的 server 是调试用的,上 php-fpm 会更快,


$ ab -n 1000 -c 1000 "http://localhost:8080/servlet-test-1.0-SNAPSHOT/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: /servlet-test-1.0-SNAPSHOT/x.png
Document Length: 70 bytes

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

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 3.5 0 11
Processing: 1 24 13.6 21 74
Waiting: 1 22 12.5 19 72
Total: 3 26 15.3 21 83

Percentage of the requests served within a certain time (ms)
50% 21
66% 27
75% 32
80% 36
90% 51
95% 59
98% 67
99% 71
100% 83 (longest request)





代码:


import java.io.IOException;
import java.io.OutputStream;
import java.util.Base64;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* Servlet implementation class XServlet
*/
public class XServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

/**
* @see HttpServlet#HttpServlet()
*/
public XServlet() {
super();
// TODO Auto-generated constructor stub
}

/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setHeader("content-type","image/png");
String onepointpngBase64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWP4////fwAJ+wP9CNHoHgAAAABJRU5ErkJggg==";
OutputStream os = response.getOutputStream();
byte[] decodedValue = Base64.getDecoder().decode(onepointpngBase64);
os.write(decodedValue);
}

/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}

}
zjsxwc
2019-09-23 12:43:26 +08:00
我收回说的这句话,java 只是在第一次跑的时候会比 php 慢,之后多次访问后会快很多
reus
2019-09-23 12:59:34 +08:00
所以就是 java 没预热……
auciou2
2019-09-23 13:03:04 +08:00
PHP 7.0 ~ 7.3 的速度差异不大。
PHP 7.4 速度约是 7.3 的 1.8 ~ 2 倍。使用 PHP 7.4 测试,会更有惊喜。
zjsxwc
2019-09-23 13:45:32 +08:00
@reus 是的


不过最后测下来,感觉性能都差不多,和 io 有关把,我把 Linux ulimit 调到 10001 也是这个结果,再大我的电脑调不上去了,两者耗时还是差不多
Xusually
2019-09-23 14:50:07 +08:00
PHP 你用的还是 7.0 如果用的是目前各大发行版仓库里默认的 7.2.22 或者换 7.3 系列估计还会有 10%-15%的提升。还在测试的 7.4 和 8 的效率就更高一些。
zjsxwc
2019-09-23 15:06:18 +08:00
@Xusually

我系统是 Linux Deepin,apt install php 给我装了 7.0,就没有去换,汗
iminto
2019-09-23 15:26:10 +08:00
其实是 JDK 内置的 Base64 太慢了,而且基于 servlet 的模式也不快
chengyiqun
2019-09-23 15:53:37 +08:00
java 预热以后, 性能才能体现出来. 预热后变成机器码, 性能才接近 C++
-XX:CompileThreshold
这个参数了解下.
richzhu
2019-09-23 15:58:16 +08:00
😱不会吧 go 这么差的嘛
iminto
2019-09-23 16:13:47 +08:00
@iminto 用 vert.x 跑 HTTP 服务性能会好很多,再用上 JODD 里的 base64。

早期的 base64 性能测试: https://www.oschina.net/code/snippet_724468_15551
wysnylc
2019-09-23 16:17:00 +08:00
java12 之前有 jit
12 有 zgc
我这个挖掘机好难开还没铲子快,大概就是你这个问题的比喻
gz911122
2019-09-23 16:18:14 +08:00
可以用 vertx 试一下...
spring 那一套调用栈都能超过 2 个屏幕...性能损耗比较大...
Hanggi
2019-09-23 16:30:49 +08:00
php 和 node.js 谁更快?
反正 python 最慢。
wengjin456123
2019-09-23 16:34:53 +08:00
PHP7 以后快了很多

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

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

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

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

© 2021 V2EX