将大量数据加载到内存中--这是最有效的方法吗?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (20)

我有一个基于Web的文档搜索/查看系统,我正在为一个客户开发。这个系统的一部分是一个搜索系统,它允许客户端搜索一个术语。斯载于文件中。我已经创建了必要的搜索数据文件,但是有很多数据需要加载,加载所有数据需要8到20秒。根据需要搜索哪些文档,将数据分解为40-100个文件。每个文件在40到350 kb之间。

此外,该应用程序必须能够在本地文件系统上运行,也可以通过Web服务器运行。

当网页加载时,我可以生成一个列表,列出我需要加载的搜索数据文件。必须加载整个列表,才能将网页视为功能。

当我知道整个网页都被加载后,我调用了loadData()函数

function loadData(){
            var d = new Date();
            var curr_min = d.getMinutes();
            var curr_sec = d.getSeconds();
         var curr_mil = d.getMilliseconds();
         console.log("test.js started background loading, time is: " + curr_min + ":" + curr_sec+ ":" + curr_mil);
          recursiveCall();
      }


   function recursiveCall(){
      if(file_array.length > 0){
         var string = file_array.pop();
         setTimeout(function(){$.getScript(string,recursiveCall);},1);
    }
    else{
        var d = new Date();
        var curr_min = d.getMinutes();
        var curr_sec = d.getSeconds();
        var curr_mil = d.getMilliseconds();
        console.log("test.js stopped background loading, time is: " + curr_min + ":" + curr_sec+ ":" + curr_mil);
    }
  }

这样做是按顺序处理一个文件数组,在文件之间中断1ms。这有助于防止浏览器在加载过程中被完全锁定,但是浏览器仍然倾向于通过加载数据而陷入困境。我正在加载的每个文件如下所示:

AddToBookData(0,[0,1,2,3,4,5,6,7,8]);
AddToBookData(1,[0,1,2,3,4,5,6,7,8]);
AddToBookData(2,[0,1,2,3,4,5,6,7,8]);

其中,每一行都是一个函数调用,用于向数组中添加数据。“AddToBookData”函数只执行以下操作:

    function AddToBookData(index1,value1){
         BookData[BookIndex].push([index1,value1]);
    }

这是现行的制度。加载所有数据后,“AddToBookData”可以被调用100,000次以上。

我认为这是非常低效率的,所以我编写了一个脚本来接受test.js文件,其中包含上面所有的函数调用,并将它处理成一个巨大的数组,这个数组相当于BookData正在创建的数据结构。我没有执行旧系统所做的所有函数调用,而只是执行以下操作:

var test_array[..........(data structure I need).......]
BookData[BookIndex] = test_array;

我希望看到性能的提高,因为我删除了上面所有的函数调用,这个方法需要更多的时间来创建准确的数据结构。我应该注意到“测试”_在我的真实世界测试中,数组“容纳了90,000多个元素。

两种加载数据的方法的CPU利用率似乎大致相同。我惊讶地发现了这一点,因为我期望第二种方法只需要很少的CPU时间,因为数据结构是在手工创建之前创建的。

提问于
用户回答回答于

看起来,优化数据加载有两个基本领域,可以分别考虑和处理:

  1. 从服务器下载数据。而不是一个大文件,你应该从多个小文件的并行负载中获得胜利。尝试同时加载的数量,记住浏览器的限制和具有太多并行连接的递减回报。在jsfiddle上进行实验,但是要记住,由于从GitHub提取测试数据的变化无常,结果会有所不同--最好是在更严格控制的条件下使用自己的数据进行测试。
  2. 尽可能高效地构建数据结构。你的结果就像一个多维数组,在JavaScript数组上,性能可能会给您提供一些在这方面进行实验的想法。

使用Web工作者

标浏览器可能不支持,但应防止主浏览器线程在处理数据时锁定。

对于没有工作人员的浏览器,可以考虑增加setTimeout稍作间隔,让浏览器有时间为用户和JS服务。这将使事情实际上稍微慢一些,但结合下一点可能会增加用户的幸福感。

提供进展反馈

对于支持工人的浏览器和缺乏工作人员的浏览器,都需要一些时间来使用进度条更新DOM。有多少文件需要加载,所以进度应该相当一致,如果他们得到了反馈,并且不认为浏览器已经锁定了他们。

懒惰加载

在他的评论中,如果GoogleInstant可以在我们输入的时候搜索整个网站。

用户回答回答于

我测试了三种方法,将相同的9,000,000点数据集加载到Firefox 3.64中。

1: Stephen's GetJSON Method
2) My function based push method
3) My pre-processed array appending method:

我以两种方式运行我的测试:我导入了100个包含10,000行数据的文件,每一行包含9个数据元素。0 1,2,3,4,5,6,7,8

第二次交互,我尝试合并文件,所以我导入了一个文件与900万个数据点。

这比我将要使用的数据集要大得多,但它有助于演示各种导入方法的速度。

Separate files:                 Combined file:

JSON:        34 seconds         34
FUNC-BASED:  17.5               24
ARRAY-BASED: 23                 46

在加载每个网页后,我关闭了浏览器,每次运行4次测试,以尽量减少网络流量/变化的影响(使用文件服务器跨网络运行)。你看到的数字是平均数,尽管单个跑步最多只相差一两秒钟。

扫码关注云+社区