怎么提高在大量数据中频繁搜索时的速度

请问大家,在对大量数据中搜索时,怎么提高速度。我本来以为findall有类似findnext的性能问题。在issue里搜了一下,发现也没有。然后我就改了一个不用findall的版本,从benchmark看,并没有多大提升。
然后我又试了一下,应该是和数据量有关系。dov_all的数据量大概在300万,减少数据量到10000提升就很明显了。
我觉得这可能不是julia语言的问题了,但还是希望大家给点意见。

function search_point(lon::T,lat::T,limit::T,all_data::Array{T,2}) where {T<:Float64}

    flag1=findall(x-> lon+limit >= x >= lon-limit,all_data[:,1])
    flag2=findall(x-> lat+limit >= x >= lat-limit,all_data[:,2])
    return all_data[intersect(flag1,flag2),:]
end

julia> @benchmark point_list=search_point(110.0,10.0,2/60/2,$dov_all)
BenchmarkTools.Trial:
  memory estimate:  30.75 MiB
  allocs estimate:  75
  --------------
  minimum time:     11.407 ms (0.00% GC)
  median time:      11.823 ms (0.00% GC)
  mean time:        13.111 ms (10.63% GC)
  maximum time:     20.530 ms (43.83% GC)
  --------------
  samples:          381
  evals/sample:     1

function search_point(lon::T,lat::T,limit::T,all_data::Array{T,2}) where {T<:Float64}

    flag1=@. lon+limit > all_data[:,1]> lon-limit
    temp=all_data[flag1,:]
    flag2=@. lat+limit > temp[:,2]> lat-limit

    return temp[flag2,:]
end
julia> @benchmark point_list=search_point(110.0,10.0,2/60/2,$dov_all)
BenchmarkTools.Trial:
  memory estimate:  15.60 MiB
  allocs estimate:  29
  --------------
  minimum time:     11.108 ms (0.00% GC)
  median time:      11.679 ms (0.00% GC)
  mean time:        12.380 ms (5.61% GC)
  maximum time:     21.287 ms (19.34% GC)
  --------------
  samples:          404
  evals/sample:     1

julia> @benchmark point_list=search_point(110.0,10.0,2/60/2,$dov_all[1:10000,:])
BenchmarkTools.Trial:
  memory estimate:  419.38 KiB
  allocs estimate:  25
  --------------
  minimum time:     103.835 μs (0.00% GC)
  median time:      110.987 μs (0.00% GC)
  mean time:        140.061 μs (17.53% GC)
  maximum time:     12.806 ms (98.27% GC)
  --------------
  samples:          10000
  evals/sample:     1

没有看过你的数据,但是推荐你用juliaDB,可以内建索引,类似数据库的索引机制,详细能提升多少不知道,但是是会快很多,前提你的操作索引能起作用

楼上说的对,百万级需要经常性的搜索还是上数据库吧。按需弄个索引妥妥的。

(毫秒级我觉得还行啊

数据其实很简单,就是二维的数据,对第一列和第二列符合进行筛选。我简单看了下您推荐的 juliaDB 感觉不适合我这种数据。还有我看juliaDB里使用了并行,其实我这个操作已经在并行里了,好像没办法通过并行提高速度了。不知道不用并行的速度是不是也很快

# 数据类似这样,只是有很多行
julia> dov_all
2×4 Array{Float64,2}:
 110.0  20.0   2.0  -1.0
 112.0  10.2  -0.2  -1.5

我不清楚这么大数据毫秒级是什么概念。但是我因为有频繁的搜索,累积起来就感觉太慢了。还有,您觉得把这部分写成 C 会快吗

没实操过,口嗨一下。

用 C 重写都能接受。
那就先试试空间换时间。不知道你的 dov_all 变不变。
不变就多弄几个副本,分别按查找时使用的按索引排序,然后再用。

用 C 重写感觉是没必要的,julia 的优化还是有保障的。
你得先排除算法问题,再试试数据库,看看查询的开销怎么样。
数据库建好索引,全塞到内存里,速度肯定是没得说。值得担心的地方是可能查一次的开销有点大。

我的建议是:
空间换时间 > 数据库 > julia 重写查找/换算法 > C 重写

function search_point1(lon::T,lat::T,limit::T,all_data::Array{T,2}) where {T<:Float64}

return all_data[(lon+limit .>= all_data[:,1].>= lon-limit) .& (lat+limit .>= all_data[:,2] .>= lat-limit),:]

end
试试这个

谢谢回复。不过您这种方法,更慢了,比第一种方法大概慢了5ms。我再试试上面说到的方法。

有没有一个小一些的样例数据给大家重复你的结果呢?