按CPU交易RAM(性能问题)

时间:2017-01-02 11:26:45

标签: javascript node.js cpu ram

我正在处理一个处理文件的程序,我可以做几件事,比如重命名,阅读它们的内容等等。

今天我按如下方式对其进行初始化:

return new Promise((resolve, reject) => {
  glob("path/for/files/**/*", {
    nodir: true
  }, (error, files) => {
    files = files.map((file) => {
      // properties like full name, basename, extension, etc.
    });
    resolve(files);
  });
});

因此,我读取了特定目录的内容,返回数组中的所有文件,然后使用Array.map迭代数组并更改具有属性的对象的路径。

有时我使用200.000个文本文件,因此,这会成为一个问题,因为它占用了太多的RAM。

所以,我希望用延迟加载替换构造函数..但我之前从未这样做过......所以我正在寻找帮助之手。

那是我的代码:

class File {
  constructor(path) {
    this.path = path;
  }

  extension() {
    return path.extname(this.path);
  }
  // etc
}

所以,我的主要问题是:我应该只返回属性的评估,还是应该替换它?像这样:

extension() {
  this.extension = path.extname(this.path);
}

我知道这是一个折衷方案..我将通过cpu使用来交换内存。

谢谢。

3 个答案:

答案 0 :(得分:0)

如果您想减少RAM使用量,我建议您为每条路径存储额外的元数据文件,如下所示:

  1. 根据需要将路径保留在内存或其中一些路径中。

  2. 将文件属性保存到硬盘

  3. files.forEach( (file) => { 
      // collect the properties you want for the file
      // ...
      var json = { path: file, extension: extension, .. }
    
      // mark the metadata file so you can access it later, for example: put it in the same path with a suffix
      var metaFile = path + '_meta.json';
      fs.writeFile(metaFile, JSON.stringify(json), (err) => {
        if (err) throw err;
      }); 
    });

    现在所有元数据都在硬盘上。我相信,这样就可以为磁盘空间和CPU调用交换内存。

    1. 如果您希望获取文件的属性,只需阅读并JSON.parse其对应的元数据文件。

答案 1 :(得分:0)

没有理由将CPU换成空间。只需走过树并处理找到的文件即可。如果树首先完成深度,那么步行树所需的空间与树深度成正比。这几乎肯定与仅在现有代码中创建路径列表具有相同的开销。

对于目录漫游,node.js FAQ建议node-findit。那里的文件很清楚。您的代码将类似于:

var finder = require('findit')(root_directory);
var path = require('path');
var basenames = [];

finder.on('file', function (file, stat) {
  basenames.push(path.basename(file));
  // etc
}

或者,如果您愿意,可以将捕获的值包装在对象中。

答案 2 :(得分:0)

如果只存储路径属性NodeJS类实例,则为您的示例200k * (path.length * 2 + 6)字节存储器。

如果要对基本名称使用延迟加载,则扩展等使用延迟getter

class File {
  constructor(path) {
     this.path = path;
     this._basename = null;
     this._extname = null;
  }
  get extname() {
     return this._extname || (this._extname = path.extname(this.path));
  }
  get basename() {
     return this._basename || (this._basename = path.basename(this.path));
  }
}