Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/73.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_Jquery_Data Structures - Fatal编程技术网

Javascript 将大量数据加载到内存-最有效的方法?

Javascript 将大量数据加载到内存-最有效的方法?,javascript,jquery,data-structures,Javascript,Jquery,Data Structures,我有一个基于网络的文档搜索/查看系统,我正在为客户开发。该系统的一部分是一个搜索系统,允许客户端搜索文档中包含的术语。我已经创建了必要的搜索数据文件,但是有很多数据需要加载,加载所有数据需要8-20秒。根据需要搜索的文档,数据被分为40-100个文件。每个文件的大小在40-350kb之间 此外,此应用程序必须能够在本地文件系统上运行,以及通过Web服务器运行 当网页加载时,我可以生成需要加载的搜索数据文件列表。必须先加载整个列表,才能将网页视为可用 有了序言,让我们看看我现在是怎么做的 在知道整

我有一个基于网络的文档搜索/查看系统,我正在为客户开发。该系统的一部分是一个搜索系统,允许客户端搜索文档中包含的术语。我已经创建了必要的搜索数据文件,但是有很多数据需要加载,加载所有数据需要8-20秒。根据需要搜索的文档,数据被分为40-100个文件。每个文件的大小在40-350kb之间

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

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

有了序言,让我们看看我现在是怎么做的

在知道整个网页已加载后,我调用loadData()函数

这样做的目的是按顺序处理一组文件,在文件之间间隔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]);
{
    "key" : 0,
    "values" : [0,1,2,3,4,5,6,7,8]
}
function AddToBookData(json) {
     BookData[BookIndex].push([json.key,json.values]);
}
[
    {
        "key" : 0,
        "values" : [0,1,2,3,4,5,6,7,8]
    },
    {
        "key" : 1,
        "values" : [0,1,2,3,4,5,6,7,8]
    },
    {
        "key" : 2,
        "values" : [0,1,2,3,4,5,6,7,8]
    }
]
{
    "file1" : [
        {
            "key" : 0,
            "values" : [0,1,2,3,4,5,6,7,8]
        },
        // all the rest...
    ],
    "file2" : [
        {
            "key" : 1,
            "values" : [0,1,2,3,4,5,6,7,8]
        },
        // yadda yadda
    ]
}
其中每一行都是一个函数调用,用于向数组中添加数据。“AddToBookData”函数仅执行以下操作:

    function AddToBookData(index1,value1){
         BookData[BookIndex].push([index1,value1]);
    }
var test_array[..........(data structure I need).......]
BookData[BookIndex] = test_array;
这是现行的制度。加载所有数据后,“AddToBookData”可以被调用100000次以上

我认为这是非常低效的,因此我编写了一个脚本来获取包含上述所有函数调用的test.js文件,并对其进行处理以将其更改为一个巨大的数组,该数组与BookData正在创建的数据结构相同。我没有像旧系统那样进行所有函数调用,而是简单地执行以下操作:

    function AddToBookData(index1,value1){
         BookData[BookIndex].push([index1,value1]);
    }
var test_array[..........(data structure I need).......]
BookData[BookIndex] = test_array;
我希望看到性能的提高,因为我删除了上面所有的函数调用,这个方法需要稍微多一些时间来创建精确的数据结构。我应该注意到,“test_数组”在我的真实测试中包含了略多于90000个元素

这两种加载数据的方法似乎具有大致相同的CPU利用率。我很惊讶地发现这一点,因为我希望第二种方法只需要很少的CPU时间,因为数据结构是事先创建的


请告知

< P>而不是使用<代码> $.GETScript < /C> >加载包含函数调用的JavaScript文件,请考虑使用。这可能会提高性能。这些文件现在看起来如下所示:

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]);
{
    "key" : 0,
    "values" : [0,1,2,3,4,5,6,7,8]
}
function AddToBookData(json) {
     BookData[BookIndex].push([json.key,json.values]);
}
[
    {
        "key" : 0,
        "values" : [0,1,2,3,4,5,6,7,8]
    },
    {
        "key" : 1,
        "values" : [0,1,2,3,4,5,6,7,8]
    },
    {
        "key" : 2,
        "values" : [0,1,2,3,4,5,6,7,8]
    }
]
{
    "file1" : [
        {
            "key" : 0,
            "values" : [0,1,2,3,4,5,6,7,8]
        },
        // all the rest...
    ],
    "file2" : [
        {
            "key" : 1,
            "values" : [0,1,2,3,4,5,6,7,8]
        },
        // yadda yadda
    ]
}
收到JSON响应后,您可以对其调用
AddToBookData
,如下所示:

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]);
{
    "key" : 0,
    "values" : [0,1,2,3,4,5,6,7,8]
}
function AddToBookData(json) {
     BookData[BookIndex].push([json.key,json.values]);
}
[
    {
        "key" : 0,
        "values" : [0,1,2,3,4,5,6,7,8]
    },
    {
        "key" : 1,
        "values" : [0,1,2,3,4,5,6,7,8]
    },
    {
        "key" : 2,
        "values" : [0,1,2,3,4,5,6,7,8]
    }
]
{
    "file1" : [
        {
            "key" : 0,
            "values" : [0,1,2,3,4,5,6,7,8]
        },
        // all the rest...
    ],
    "file2" : [
        {
            "key" : 1,
            "values" : [0,1,2,3,4,5,6,7,8]
        },
        // yadda yadda
    ]
}
如果您的文件有多组对AddToBookData的调用,则可以按如下方式对其进行结构:

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]);
{
    "key" : 0,
    "values" : [0,1,2,3,4,5,6,7,8]
}
function AddToBookData(json) {
     BookData[BookIndex].push([json.key,json.values]);
}
[
    {
        "key" : 0,
        "values" : [0,1,2,3,4,5,6,7,8]
    },
    {
        "key" : 1,
        "values" : [0,1,2,3,4,5,6,7,8]
    },
    {
        "key" : 2,
        "values" : [0,1,2,3,4,5,6,7,8]
    }
]
{
    "file1" : [
        {
            "key" : 0,
            "values" : [0,1,2,3,4,5,6,7,8]
        },
        // all the rest...
    ],
    "file2" : [
        {
            "key" : 1,
            "values" : [0,1,2,3,4,5,6,7,8]
        },
        // yadda yadda
    ]
}
然后更改
AddToBookData
函数以补偿新结构:

function AddToBookData(json) {
    $.each(json, function(index, data) {
        BookData[BookIndex].push([data.key,data.values]);
    });
}  
附录
我怀疑,无论使用何种方法将数据从文件传输到
BookData
数组,真正的瓶颈在于请求的数量。这些文件必须分成40-100个片段吗?如果更改为JSON格式,则可以加载如下所示的单个文件:

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]);
{
    "key" : 0,
    "values" : [0,1,2,3,4,5,6,7,8]
}
function AddToBookData(json) {
     BookData[BookIndex].push([json.key,json.values]);
}
[
    {
        "key" : 0,
        "values" : [0,1,2,3,4,5,6,7,8]
    },
    {
        "key" : 1,
        "values" : [0,1,2,3,4,5,6,7,8]
    },
    {
        "key" : 2,
        "values" : [0,1,2,3,4,5,6,7,8]
    }
]
{
    "file1" : [
        {
            "key" : 0,
            "values" : [0,1,2,3,4,5,6,7,8]
        },
        // all the rest...
    ],
    "file2" : [
        {
            "key" : 1,
            "values" : [0,1,2,3,4,5,6,7,8]
        },
        // yadda yadda
    ]
}
然后你可以做一个请求,加载所有你需要的数据,然后继续。。。虽然浏览器最初可能会锁定(虽然,可能不会),但这样做可能会更快


如果您不熟悉,这里有一个不错的JSON教程:

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

1: Stephen's GetJSON Method
2) My function based push method
3) My pre-processed array appending method:
我以两种方式运行测试:在测试的第一次迭代中,我导入了100个文件,其中包含10000行数据,每行包含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次测试,以最小化网络流量/变化的影响。(通过网络运行,使用文件服务器)。您看到的数字是平均值,尽管单个运行之间的差异最多只有一秒或两秒。

看起来有两个基本的优化数据加载区域,可以单独考虑和处理:

  • 从服务器下载数据。您应该从多个较小文件的并行加载中获得胜利,而不是一个大文件。尝试同时加载的数量,记住浏览器限制和拥有太多并行连接的收益递减。请参阅我在JSFIDLE上的vs实验,但请记住,由于从github提取测试数据的变化无常,结果会有所不同-最好在更严格控制的条件下使用自己的数据进行测试
  • 尽可能高效地构建数据结构。您的结果看起来像一个多维数组,基于JavaScript的数组性能可能会为您提供一些在这方面进行实验的想法
  • 但我不确定单凭优化数据加载就可以做到什么程度。要解决应用程序的实际问题(浏览器锁定时间过长),您是否考虑过以下选项

    使用网络工作者 可能不是所有目标浏览器都支持,但应防止主浏览器线程在处理数据时锁定

    对于没有工作者的浏览器,您可以考虑稍微增加<代码> SETTIMEOUT间隔,以提供浏览器时间来服务用户以及您的JS。这将使事情实际上稍微慢一点,但当与下一点结合时,可能会增加用户的幸福感

    提供进度反馈 Fo