Node.js
代码var http = require('http'); http.createServer(function (request, response) { var num = 0 for (var i = 1; i < 5900000000; i++) { num += i } response.end('Hello' + num); }).listen(8888);
nodemon
启动服务,用time curl
调用这个接口7.xxs
耗时CPU
使用当时很高,差不多打到100%
了.但是我后面发现不是这个问题.CPU
问题,看内存消耗占用。var http = require('http'); http .createServer(function(request, response) { console.log(request.url, 'url'); let used = process.memoryUsage().heapUsed / 1024 / 1024; console.log( `The script uses approximately ${Math.round(used * 100) / 100} MB`, 'start', ); console.time('测试'); let num = 0; for (let i = 1; i < 5900000000; i++) { num += i; } console.timeEnd('测试'); used = process.memoryUsage().heapUsed / 1024 / 1024; console.log( `The script uses approximately ${Math.round(used * 100) / 100} MB`, 'end', ); response.end('Hello' + num); ![](https://imgkr2.cn-bj.ufileos.com/13455121-9d87-42c3-a32e-ea999a2cd09b.png?UCloudPublicKey=TOKEN_8d8b72be-579a-4e83-bfd0-5f6ce1546f13&Signature=E3cF2kymC92LifrIC5IOfIZQvnk%253D&Expires=1598883364) ![](https://imgkr2.cn-bj.ufileos.com/1e7b95df-2a48-41c3-827c-3c24b39f4b5b.png?UCloudPublicKey=TOKEN_8d8b72be-579a-4e83-bfd0-5f6ce1546f13&Signature=%252FANTTuhgbpIsXslXMc1qCkj2TMU%253D&Expires=1598883362) }) .listen(8888);
CPU
都正常5.9亿次
)var a = 'java' var b = a + 'script'
* 只连接100个以下的字符串建议用这种方法最方便
var arr = ['hello','java','script'] var str = arr.join("")
var a = 'java' var b = `hello ${a}script`
var a = 'java' var b = 'script' var str = a.concat(b)
function StringConnect(){ this.arr = new Array() } StringConnect.prototype.append = function(str) { this.arr.push(str) } StringConnect.prototype.toString = function() { return this.arr.join("") } var mystr = new StringConnect() mystr.append("abc") mystr.append("def") mystr.append("g") var str = mystr.toString()
join
方式(此时循环5.9
亿次)var http = require('http'); http .createServer(function(request, response) { console.log(request.url, 'url'); let used = process.memoryUsage().heapUsed / 1024 / 1024; console.log( `The script uses approximately ${Math.round(used * 100) / 100} MB`, 'start', ); console.time('测试'); let num = 0; for (let i = 1; i < 590000000; i++) { num += i; } const arr = ['Hello']; arr.push(num); console.timeEnd('测试'); used = process.memoryUsage().heapUsed / 1024 / 1024; console.log( `The script uses approximately ${Math.round(used * 100) / 100} MB`, 'end', ); response.end(arr.join('')); }) .listen(8888);
注意此时是5.9亿次循环
)《javascript高级程序设计》
中,有一段关于字符串特点的描述,原文大概如下:ECMAScript
中的字符串是不可变的,也就是说,字符串一旦创建,他们的值就不能改变。要改变某个变量的保存的的字符串,首先要销毁原来的字符串,然后再用另外一个包含新值的字符串填充该变量+
直接拼接字符串自然会对性能产生一些影响,因为字符串是不可变的,在操作的时候会产生临时字符串副本,+
操作符需要消耗时间,重新赋值分配内存需要消耗时间。var http = require('http'); http .createServer(function(request, response) { console.log(request.url, 'url'); let used = process.memoryUsage().heapUsed / 1024 / 1024; console.log( `The script uses approximately ${Math.round(used * 100) / 100} MB`, 'start', ); console.time('测试'); let num = 0; for (let i = 1; i < 5900000000; i++) { // num++; } const arr = ['Hello']; // arr[1] = num; console.timeEnd('测试'); used = process.memoryUsage().heapUsed / 1024 / 1024; console.log( `The script uses approximately ${Math.round(used * 100) / 100} MB`, 'end', ); response.end('hello'); }) .listen(8888);
for
循环的耗时不一致var http = require('http'); http .createServer(function(request, response) { console.log(request.url, 'url'); let used = process.memoryUsage().heapUsed / 1024 / 1024; console.log( `The script uses approximately ${Math.round(used * 100) / 100} MB`, 'start', ); let num = 0; console.time('测试'); for (let i = 1; i < 5900000000; i++) { // num++; } console.timeEnd('测试'); const arr = ['Hello']; // arr[1] = num; used = process.memoryUsage().heapUsed / 1024 / 1024; console.log( `The script uses approximately ${Math.round(used * 100) / 100} MB`, 'end', ); response.end('hello'); }) .listen(8888);
for
循环内部的i++
其实就是变量不断的重新赋值覆盖40亿次
跟50亿次
的区别,差距很大,40亿次的for循环
,都是稳定的,但是50亿次
就不稳定了.Node.js
的EventLoop
:CPU
使用情况60亿
次的循环,像有使用多进程异步计算的,但是本质上没有解决这部分循环代码的调用耗时。for
循环:var http = require('http'); http .createServer(function(request, response) { console.log(request.url, 'url'); let used = process.memoryUsage().heapUsed / 1024 / 1024; console.log( `The script uses approximately ${Math.round(used * 100) / 100} MB`, 'start', ); let num = 0; console.time('测试'); for (let i = 1; i < 600000; i++) { num++; for (let j = 0; j < 10000; j++) { num++; } } console.timeEnd('测试'); const arr = ['Hello']; console.log(num, 'num'); arr[1] = num; used = process.memoryUsage().heapUsed / 1024 / 1024; console.log( `The script uses approximately ${Math.round(used * 100) / 100} MB`, 'end', ); response.end(arr.join('')); }) .listen(8888);
60亿次
循环总共:+
方式拼接字符串var http = require('http'); http .createServer(function(request, response) { console.log(request.url, 'url'); let used = process.memoryUsage().heapUsed / 1024 / 1024; console.log( `The script uses approximately ${Math.round(used * 100) / 100} MB`, 'start', ); let num = 0; console.time('测试'); for (let i = 1; i < 600000; i++) { num++; for (let j = 0; j < 10000; j++) { num++; } } console.timeEnd('测试'); // const arr = ['Hello']; console.log(num, 'num'); // arr[1] = num; used = process.memoryUsage().heapUsed / 1024 / 1024; console.log( `The script uses approximately ${Math.round(used * 100) / 100} MB`, 'end', ); response.end(`Hello` + num); }) .listen(8888);
Node.js
的运行耗时是稳定,但是如果是循环次数过多,那么就会出现刚才那种情况,阻塞严重,耗时不一样。CPU
有一些关系,因为top
查看一直是在升高i
的值到60亿
,还要不断更新num
的值60亿
,内存使用会不断上升,最终出现两份60亿
的数据,然后再回收。(因为GC自动垃圾回收,一样会阻塞主线程
,多次接口调用后,CPU
占用也会升高)for
循环拆解后:for (let i = 1; i < 60000; i++) { num++; for (let j = 0; j < 100000; j++) { num++; } }
num
到60亿
即可,解决了这个问题。如果是异步的业务场景,也可以用多进程参与解决超大计算量问题,今天这里就不重复介绍了
在看
/赞
,转发一下,让更多人看到Peter谭老师
,欢迎你关注公众号:前端巅峰
,后台回复:加群
即可加入大前端交流群