Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/38.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何提高JS中函数代码的性能_Javascript_Node.js_Performance_Functional Programming - Fatal编程技术网

Javascript 如何提高JS中函数代码的性能

Javascript 如何提高JS中函数代码的性能,javascript,node.js,performance,functional-programming,Javascript,Node.js,Performance,Functional Programming,我正在努力学习函数式编程,但我无法理解这一点。在我的最小工作示例中,我有一个字典列表,每个字典包含一个文件名和文件大小。我想创建一个新的字典,按大小对文件进行分组(这是查找重复文件的更大算法的一部分) 以下是处理这种变异数据的“传统”方法: constgroupfilesbysize=(allFileData)=>{ const filesSortedBySize={}; for(所有文件数据的常量文件数据){ if(filesortedBySize中的fileData.size){ FileS

我正在努力学习函数式编程,但我无法理解这一点。在我的最小工作示例中,我有一个字典列表,每个字典包含一个文件名和文件大小。我想创建一个新的字典,按大小对文件进行分组(这是查找重复文件的更大算法的一部分)

以下是处理这种变异数据的“传统”方法:

constgroupfilesbysize=(allFileData)=>{
const filesSortedBySize={};
for(所有文件数据的常量文件数据){
if(filesortedBySize中的fileData.size){
FileSortedBySize[fileData.size].push(fileData.file);
}否则{
FileSortedBySize[fileData.size]=[fileData.file];
}
}
返回文件分类数据库;
};
以下是我以实用的方式“最佳”尝试:

constgroupfilesbysizefunction=(allFileData)=>
allFileData.reduce(
(FileSortedBySize,fileData)=>({
…文件分类数据库,
[fileData.size]:FileSortedBySize[fileData.size]
?[…FileSortedBySize[fileData.size],fileData.file]
:[fileData.file]
}),
{}
);
我已经对它们进行了基准测试(下面的可复制示例),功能版本大约慢了10000倍。这可不是开玩笑——它简直无法使用。我可以想象,每次我们在
reduce
中处理一个文件时,都会创建一个新的字典,这就是造成延迟的原因

尽管如此,现在我看到了两种可能性:要么函数式编程的性能糟糕,要么我无法编写正确的函数式代码。显然,第二种方法是正确的,我想问:以函数方式编写函数
groupFilesBySize
的正确方法是什么?


基准测试: 使用此函数可获取文件数组路径和文件大小:

异步函数遍历(dir){
让文件=[];
files=wait fs.readdir(dir);
const parsedFiles=wait Promise.all(files.map)(异步(文件名)=>{
const filePath=path.join(dir,fileName);
const stats=wait fs.lstat(文件路径);
if(stats.isSymbolicLink()| | stats.size==0){
返回null;
}
if(stats.isDirectory()){
返回漫游(文件路径);
}else if(stats.isFile()){
返回{file:filePath,size:stats.size};
}
}));
返回parsedFiles.reduce(
(全部,folderContents)=>(folderContents?全部.concat(folderContents):全部),
[]
);
}
然后使用以下方法对所有内容进行基准测试:

const benchMark=async()=>{
const dir=path.dirname(_文件名);
const allFileData=wait walk(dir);
log(`Total files:${allFileData.length}`);
开始=新日期();
const result1=groupFilesBySize(allFileData);
const time1=新日期()-开始;
开始=新日期();
const result2=groupfilesbysizefunction(allFileData);
const time2=新日期()-开始;
console.log('\n最终报告:')
log(`results equal?${JSON.stringify(result1)==JSON.stringify(result2)}`);
log(`非功能性方法:${time1}ms`);
log(`Functional approach:${time2}ms`);
};
为了获得可观的数据,我选择安装node包
eslint
,因此我必须将
node\u modules
文件夹中的所有文件分组:
npm install eslint
。我的机器中的输出:

Total files: 6229

FINAL REPORT:
Are results equal? true
Non functional approach: 6 ms
Functional approach: 34557 ms

如果您在reduce中进行了变异,那么就没有问题了,您将稍微提高性能

constgroupfilesbysizefunctional=allFileData=>
allFileData.reduce(
(FileSortedBySize,fileData)=>
Object.assign(filesSortedBySize{
[fileData.size]:FileSortedBySize[fileData.size]
?[…FileSortedBySize[fileData.size],fileData.file]
:[fileData.file]
}),
{}
);

如果在reduce中进行变异,则不会出现问题,并且会稍微提高性能

constgroupfilesbysizefunctional=allFileData=>
allFileData.reduce(
(FileSortedBySize,fileData)=>
Object.assign(filesSortedBySize{
[fileData.size]:FileSortedBySize[fileData.size]
?[…FileSortedBySize[fileData.size],fileData.file]
:[fileData.file]
}),
{}
);

如果您想使用函数式编程范例,请确保您使用的是函数式数据结构,如提供的数据结构

const{Map,List}=不可变;
const groupFilesBySize=allFileData=>
allFileData.reduce((FileSortedBySize,{size,file})=>
filesortedBySize.update(大小,List(),List=>List.push(文件)),Map();
常量allFileData=[
{大小:12,文件:“你好,世界!”},
{size:3,文件:“foo”},
{size:3,文件:“bar”},
{size:6,文件:“foobar”},
{大小:12,文件:“你好,世界!”},
{size:4,文件:“fizz”},
{size:4,文件:“buzz”},
{大小:8,文件:“fizzbuzz”},
];
console.time(“groupFilesBySize”);
对于(设i=0;i<1e6;i++)groupFilesBySize(allFileData);
console.timeEnd(“groupFilesBySize”);
log(groupFilesBySize(allFileData))

如果您想使用函数式编程范例,那么请确保您使用的是函数式数据结构,例如由提供的数据结构

const{Map,List}=不可变;
const groupFilesBySize=allFileData=>
allFileData.reduce((FileSortedBySize,{size,file})=>
filesortedBySize.update(大小,List(),List=>List.push(文件)),Map();
常量allFileData=[
{大小:12,文件:“你好,世界!”},
{size:3,文件:“foo”},
{size:3,文件:“bar”},
{size:6,文件:“foobar”},
{大小:12,文件:“你好,世界!”},
{size:4,文件:“fizz”},
{size:4,文件:“buzz”},
{大小:8,文件:“fizzbuzz”},
];
console.time(“groupFilesBySize”);
对于(设i=0;i<1e6;i++)groupFilesBySize(allFileData);
控制台