<返回更多

60亿次for循环,原来这么多东西

2020-09-25    
加入收藏
60亿次for循环,原来这么多东西

 

作者: Peter 谭老师

转发链接:https://mp.weixin.qq.com/s/Vs8CwdGJ6JUyH_Kp0H5l4Q

起因

 

60亿次for循环,原来这么多东西

 

问题重现

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);
60亿次for循环,原来这么多东西

 

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',
    );    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);
60亿次for循环,原来这么多东西

 

定位问题在字符串拼接,先看看字符串拼接的几种方式

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()

更换字符串的拼接方式

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);
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',
    );
    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);
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);
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);

推翻字符串的拼接耗时说法

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);

总结:

深度分析问题

 for (let i = 1; i < 60000; i++) {
      num++;
      for (let j = 0; j < 100000; j++) {
        num++;
      }
    }

哪些场景会遇到这个类似的超大计算量问题:

如果是异步的业务场景,也可以用多进程参与解决超大计算量问题,今天这里就不重复介绍了

作者: Peter 谭老师

转发链接:https://mp.weixin.qq.com/s/Vs8CwdGJ6JUyH_Kp0H5l4Q

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>