Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.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_Optimization - Fatal编程技术网

Javascript 优化通过长字符串工作的函数

Javascript 优化通过长字符串工作的函数,javascript,optimization,Javascript,Optimization,我在javascript中有一个很长的字符串,它需要javascript中的许多函数来处理 调用字符串: var str; 连续函数从最后一个函数停止的位置开始。因此,我保留了一个变量strPos,以指示我在字符串中的位置 每个函数沿字符串返回新位置,即 function MyStringFunction(str, strPos){ /* Does some fantastic work on the str without changing it */ /* Say th

我在javascript中有一个很长的字符串,它需要javascript中的许多函数来处理

调用字符串:

 var str;
连续函数从最后一个函数停止的位置开始。因此,我保留了一个变量
strPos
,以指示我在字符串中的位置

每个函数沿字符串返回新位置,即

function MyStringFunction(str, strPos){
    /* Does some fantastic work on the str without changing it */

    /* Say this function move strPos on 10 characters so we return */
    return (10 + strPos);
}
这是做事情最快的最佳方式吗

我应该减少字符串吗

// NOW RETURNS THE SHORTENED STRING MINUS THE STUFF I HAVE NOW WORKED ON
// strPos is now always the start of the string, as that is now where I left off
function MyStringFunction(str){
    /* Does some fantastic work on the str without changing it */

    /* Say this function works on 10 characters so we return */
    return str.substr(10);
}

哪种方法最快?请注意,字符串的开头大约有20000个字符长。

当然,性能将取决于js引擎的实现及其可能引入的优化。但从理论上讲,通过基于索引的方法进行字符串遍历将更具性能。关键是JS中的字符串是一个基于索引的无符号16位整数的不可变列表。由此我得出两个简单的结论:

  • 基于索引的部分意味着保证有O(1) 访问字符串的任何元素时的复杂性

  • 不可变部分意味着,即使一个人成功地将所有计算流构建为一个链 仍然需要浪费一些计算时间的函数调用 在每次调用期间创建子字符串的时间。所以这对我来说没什么意义

  • 在这里,我做了一些非常基本的基准测试。当然,与严肃的测试相比,这算不了什么,但仍然可以做到:

    const INIT = {
      str: 'x'.repeat(10e6),
      i: 0,
      startTime: 0,
    };
    
    let t = {};
    
    const setup = () => {
      t = { ...INIT, startTime: Date.now() };
    }
    
    const fooIndexApproach = (str, idx) => {
      const upto = idx + 10;
      for (let i = idx; i < upto; i++) str.charCodeAt(i);
      return upto;
    }
    const fooSubStrApproach = (str) => {
      for (let i = 0; i < 10; i++) str.charCodeAt(i);
      return str.slice(10);
    }
    
    
    // the first run-by is not taken into account as 'warmed-up' engine optimizations
    // may affect the performance 
    setup();
    for (let j = 0; j < 10e3; j++);
    while ((t.i = fooIndexApproach(t.str, t.i)) < t.str.length) { };
    
    setup();
    for (let j = 0; j < 10e3; j++);
    while ((t.i = fooIndexApproach(t.str, t.i)) < t.str.length) { };
    console.log(`fooIndexApproach: ${(Date.now() - t.startTime)}ms`);
    
    
    // the first run-by is not taken into account as 'warmed-up' engine optimizations
    // may affect the performance 
    setup();
    for (let j = 0; j < 10e3; j++);
    while (t.str = fooSubStrApproach(t.str)) { };
    
    setup();
    for (let j = 0; j < 10e3; j++);
    while (t.str = fooSubStrApproach(t.str)) { };
    console.log(`fooSubStrApproach: ${(Date.now() - t.startTime)}ms`);
    
    // ==============================================
    // RESULTS on my Mac:
    // substring VS indexed => [[51, 19], [51, 20]]ms
    // indexed VS substring => [[31, 52], [32, 52]]ms
    
    const INIT={
    str:'x'。重复(10e6),
    i:0,
    开始时间:0,
    };
    设t={};
    常量设置=()=>{
    t={…INIT,startTime:Date.now()};
    }
    常量foodIndexApproach=(str,idx)=>{
    常数高达=idx+10;
    对于(设i=idx;i{
    对于(设i=0;i<10;i++)str.charCodeAt(i);
    返回str.slice(10);
    }
    //第一次运行不作为“预热”发动机优化考虑
    //可能会影响性能
    设置();
    对于(设j=0;j<10e3;j++);
    而((t.i=foodindexapproach(t.str,t.i))[[51,19],[51,20]]ms
    //索引VS子字符串=>[[31,52],[32,52]]ms
    
    我必须说,这些数字不言自明。索引方法获胜,这并不奇怪