嗨其他Elixir程序员.
我有大约2.500个音乐曲目的列表,我想按不同的参数排序,例如曲目的标题.
排序应该不区分大小写.
下面的代码有效,但需要大约100ms到130ms来对列表进行排序.有更快的方法吗?对我来说,一个参考是Node.js,它在使用时大约需要25msArray.prototype.sort
编辑:对不起,我实际上已经不合时宜了.排序发生在大约30ms.但是,我仍然希望你的意见:排序能否更快完成?
谢谢.
defmodule MusicServer.Tracks.SortTracks do
def sort_tracks(tracks, "title", "desc") do
Enum.sort(tracks, fn track1, track2 ->
first_char(track1["title"]) <= first_char(track2["title"])
end)
end
def first_char(string) do
string
|> String.at(0)
|> String.downcase()
end
end
Run Code Online (Sandbox Code Playgroud)
数据结构的一个例子:
[
%{
"artist" => "Rolling Stones",
"title" => "Start It Up",
"bpm" => 100,
"createdAt" => "2018-04-27T09:08:04.428Z",
"updatedAt" => "2018-07-14T14:28:17.771Z"
},
%{
"artist" => "Al Green",
"title" => "Let's Stay Together",
"bpm" => 123,
"createdAt" => "2018-04-27T09:08:04.428Z",
"updatedAt" => "2018-07-14T14:28:17.771Z"
},
...
]
Run Code Online (Sandbox Code Playgroud)
Enum.sort将调用比较器函数的n log(n)次数,这意味着first_char将被称为2n log(n)时间,这可能是这里的瓶颈.要减少调用first_char,可以切换Enum.sort_by为每个元素调用一次函数,然后在排序时缓存它的值:
Enum.sort_by(tracks, fn track -> first_char(track["title"]) end)
Run Code Online (Sandbox Code Playgroud)
对于长度为2,500的列表,呼叫次数first_char将从超过50k减少到2.5k.当然,sort_by必须做工作分配数据结构来存储计算值,但对于这个输入它应该仍然更快.在使用之前,您应该自己仔细测试一下!