Improve program performance [closed]

房东的猫 提交于 2020-01-07 08:43:59

问题


I have a javascript program which executes operations with my JSON data (200Mega) This programm search an occurences in my datas by regxp

var myDatas = [
 { "id" : "0000000001",
   "title" :"Data1",
   "info": {
             "info1": "data data data",
             "info2": "infoinfoiinfoinfo",
             "info3": "info333333333",
             "miscellaneous": "",
             "other": [
                 {"title": "qwe", "ref": "other"},
                 {"title": "sdsd", "ref": "other"},
                 {"title": "ddd", "ref": "123"} 
             ]
           },
    "text": "xxxx text sldjdjskldj text text" },
 . . . ];

The actual execution is too slow.

I would use Worker of html 5 but IE9 it's not supported by IE9.

MY PROGRAMM :

    iterObject : function(obj){

        var text = $('#search-input').val() //text to search

        var self = this
        $.each(obj, function(key, value) {
            if((typeof value) == 'object'){
                self.iterObject(value)
            }
            else{
                 self.Search(text, value)
              }
          }
      }

Search : function(item, text){

        var regexThisFragment =
                          new RegExp("[^a-zA-Z0-9]+.{0,40}[^a-zA-Z]+" + 
                          item + 
                          "[^a-zA-Z]+.{0,40}[^a-zA-Z0-9]+", "i")

        while(text.match(regexThisFragment) != null)
        {
            var fragment = text.match(regexThisFragment).toString()
            console.log(fragment );
            }
        }
},

How I can improve my program?


回答1:


If the issue is that the UI is frozen during processing, you can break up the processing into chunks that are processed asynchronously. This will let the UI respond to the user.

var i = 0,
    chunkSize = 10, // This is how many to process at a time
    duration = 30;  // This is the duration used for the setTimeout

(function process() {
    // process this chunk
    var chunk = myDatas.slice(i, i += chunkSize);

    // do the next chunk
    if (i < myDatas.length)
        setTimeout(process, duration);
})();

You can tweak the chunkSize and duration as needed.

If the issue is to improve actual code performance, you need to show some code.




回答2:


The answer posted by user1689607 is interesting, but using setTimout will not execute the code asynchronously. It will be run on the same thread as the main application. What's still interesting in using a timer is that the other parts of the application will have some processing time available while timer is running.

Best way to have your application working ok on slow/fast devices is to choose a processing time and a 'release' time. You also need, since processing data might take some time, to be able to cancel it. And use a callback to handle the end of process.

The code could look something like that :

var DataProcessor = {
     dataProcessDuration : 30,
     releaseDuration : 5,
     dataProcessedCallback : function() { 
                //... somehow notify the application the result is available
                                       },
     _currentIndex : 0,
     _processing : false,
     _shouldCancel : false,
     processData : function() 
                              {   this.cancelProcessing();
                                  this._currentIndex =0;
                                  this._processing = true;
                                  // launch data process now, or give it time to cancel
                                  if (!this._shouldCancel)  this._processData();
                                  else setTimeout(this._processData.bind(this), 
                                            this.releaseDuration+this.dataProcessDuration+1);
                               },
     cancelProcessing : function() 
                               { 
                                     if (!this._processing) return;
                                     this._shouldCancel=true;
                               },
     _processData : function() {
          if (this._shouldCancel) { this._shouldCancel = false ;  
                                    this._processing = false; 
                                    return; }
           var startTime = Date.now();
           // while there's data and processing time  left.
           while  ( ( this._currentIndex < length of data)
                       && (Date.now()-startTime < this.dataProcessDuration) )
                {    var thisBatchCount=10;
                     while (thisBatchCount--)
                           {  
                              // ... process the this._currentIndex part of the data
                             this._currentIndex++;
                             if ( this._currentIndex == length of data) break;
                            }
                }
           if (this._currentIndex == (length of data) ) // the end ?
                {     this._processing = false; 
                      this.dataProcessedCallback()
                 }
           else // keep on processing after a release time
                setTimeout(this._processData.bind(this), this.releaseDuration);
                           }
}

Rq : in the main process loop you might want to fine-tune the granularity by changing thisBatchCount. If too small you waste time by over-checking Date.now(), and too big the inner processing will take too much time and you won't have the process/release ratio you have choosen.



来源:https://stackoverflow.com/questions/13399863/improve-program-performance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!