Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/448.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

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 如果显式定义了排序顺序,则排序速度非常慢_Javascript_Node.js_Sorting - Fatal编程技术网

Javascript 如果显式定义了排序顺序,则排序速度非常慢

Javascript 如果显式定义了排序顺序,则排序速度非常慢,javascript,node.js,sorting,Javascript,Node.js,Sorting,正如您可以在下面的代码中检查的那样,通过在属性名称前面加上+或-来定义排序顺序会导致排序速度大大降低。你知道为什么吗 默认排序(值):5.84ms 升序排序(+值):58.59ms 降序排序(-value):49.28ms value和+value(两者返回完全相同的排序顺序)之间存在差异这一事实让我非常困惑 让arr=[] 对于(设i=0;i{ const newKey=key.replace(/(\-\ \+)/g',) 常量顺序=键[0]='-'?-1:1 data.sort.push(

正如您可以在下面的代码中检查的那样,通过在属性名称前面加上
+
-
来定义排序顺序会导致排序速度大大降低。你知道为什么吗

默认排序(值):
5.84ms

升序排序(+值):
58.59ms

降序排序(-value):
49.28ms

value
+value
(两者返回完全相同的排序顺序)之间存在差异这一事实让我非常困惑

让arr=[]
对于(设i=0;i<10000;++i){
arr.push({u id:'doc'+i,值:Math.random(),k:i%20})
}
函数排序(…键){
让数据={}
data.sort=[]
keys.forEach(key=>{
const newKey=key.replace(/(\-\ \+)/g',)
常量顺序=键[0]='-'?-1:1
data.sort.push({
键:newKey,
订单:订单
})
})
返回数据
}
函数比较(排序数据,a,b){
for(设i=0;i\u b?data.order:-data.order
}
返回0
}
函数执行器(数据){
设r=arr.slice()
if(data.sort){
r、 排序((a,b)=>{
让r=比较(data.sort,a,b)
返回r
})
}
返回r
}
功能时间(f){
让我们开始=性能。现在()
f()
返回性能。现在()-start
}
功能测试(f,n){
设总数=0
对于(设i=0;iexec(q1)
const sortAsc=()=>exec(第2季度)
const sortDesc=()=>exec(第三季度)
log('Default Sort(value):',test(sortDefault,10).toFixed(2)+'ms')
console.log('升序排序(+值):',test(sortAsc,10).toFixed(2)+'ms')

console.log('Descending Sort(-value):',test(sortDesc,10).toFixed(2)+'ms')
更常见的做法是编写一个返回比较器的函数,尽管在这种情况下,性能差异似乎取决于V8 JS引擎在匹配正则表达式的情况下如何优化代码

因此,更规范的用法可能是:

function buildSort(...keys) {

  if (typeof keys[0] === "string") {
    keys = keys.map(key => {
        const order = key[0] === '-' ? -1 : 1
        key = key.replace(/(\-|\+)/g, '')
        return { key, order };
    })
  }

  return (a, b) => {
    for (let { key, order } of keys ) {
      const _a = a[key];
      const _b = b[key];
      if (_a !== _b) return _a > _b ? order : -order
    }
    return 0
  }
}

function exec(comparator) {
  return arr.slice().sort(comparator);
}

...

const q1 = buildSort({ key: 'value', order: 1 });
const q2 = buildSort({ key: 'value', order: -1 });
const q3 = buildSort('+value')

在我运行NodeJS 6.9.1的笔记本电脑上,传递
{key:'value',order:1}
“value”
给出了0.015秒的运行时间,而传递
“+value”
运行时间为0.46秒,即使名义上这些结果在比较器中使用的
结构中出现相同的值。

这更多的是作为注释,但太长了:对于测试场景来说,如果稍后插入键,则无法查看是否存在V8性能差异,我尝试存储一个原始密钥(regex的结果)并在第一次比较时获取对象的实际密钥(理论上应该是一个内部的或至少是可优化的字符串)

下面是相同的代码,但是在排序函数中设置了一个属性
rawkey
,而不是“key”,并且在与
if(!data.key)data.key=Object.keys(a).filter(k=>k==data.rawkey)[0]进行比较的内部获得了该键
不管是好是坏,在Chrome中,我在主板上的表现都是一样的。
该实现只是一个展示案例,并不安全,因为并非所有对象都可能具有实际属性

让arr=[]
对于(设i=0;i<10000;++i){
arr.push({u id:'doc'+i,值:Math.random(),k:i%20})
}
函数排序(…键){
让数据={}
data.sort=[]
keys.forEach(key=>{
const newKey=key.replace(/(\-\ \+)/g',)
常量顺序=键[0]='-'?-1:1
data.sort.push({
罗基:纽基,
订单:订单
})
})
返回数据
}
函数比较(排序数据,a,b){
for(设i=0;ik==data.rawkey)[0];
常数a=a[data.key]
常数b=b[data.key]
如果(\u a!==\u b)返回\u a>\u b?data.order:-data.order
}
返回0
}
函数执行器(数据){
设r=arr.slice()
if(data.sort){
r、 排序((a,b)=>{
让r=比较(data.sort,a,b)
返回r
})
}
返回r
}
功能时间(f){
让我们开始=性能。现在()
f()
返回性能。现在()-start
}
功能测试(f,n){
设总数=0
对于(设i=0;iexec(q1)
const sortAsc=()=>exec(第2季度)
const sortDesc=()=>exec(第三季度)
log('Default Sort(value):',test(sortDefault,10).toFixed(2)+'ms')
console.log('升序排序(+值):',test(sortAsc,10).toFixed(2)+'ms')

console.log('Descending Sort(-value):',test(sortDesc,10).toFixed(2)+'ms')
我发现动态构建比较函数可以避免速度减慢,并且在几乎所有情况下(尽管是最小的)测试中实际上都要快得多

让arr=[]
对于(设i=0;i<10000;++i){
设o={u id:'doc'+i,值:Math.random()}
方位推力(o)
}
功能排序键(…键){
常量数据={}
data.sort=[]
keys.forEach(key=>{
if(typeof key=='string')key=getSortObject(key)
如果(key.order==未定义)key.order=1
data.sort.push(键)
})
返回数据
}
函数getSortObject(str){
if(str.match(/^(\+\\-)/){
返回{key:str.substr(1),顺序:-1}
}否则{
返回{key:str,order:1}
}
}
功能执行器(数据,组件){
设r=arr.slice()
if(data.sort){
r、 排序(compFn(data.sort))
}
返回r
}
//旧的比较器,似乎会导致V8发动机出现优化问题。(Chrome/NodeJS/等)
功能比较(sdata){
返回函数(a,b){
对于(设i=0;i      Default ( value): 5.47ms
      Default (+value): 54.17ms
      Default (-value): 51.90ms
eval Function ( value): 3.25ms
eval Function (+value): 3.51ms
eval Function (-value): 2.99ms