嗨,Elixir 程序员。
我有大约 2.500 首音乐轨道的列表,我想按不同的参数对其进行排序,例如轨道的标题。
排序应该不区分大小写。
下面的代码有效,但需要大约 100 毫秒到 130 毫秒来对列表进行排序。有没有更快的方法来做到这一点?我的一个引用是 Node.js,它在使用 Array.prototype.sort
时在大约 25 毫秒内完成。
编辑:对不起,我实际上错误地安排了表演。排序发生在大约 30 毫秒内。但是,我仍然希望您的意见:可以更快地进行排序吗?
谢谢。
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
数据结构示例:
[
%{
"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"
},
...
]
最佳答案
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)
对于长度为 2,500 的列表,调用
first_char
的次数将从 50k 以上减少到 2.5k。当然sort_by
将不得不做分配数据结构来存储计算值的工作,但对于这个输入它应该仍然更快。在使用它之前,您应该自己仔细地对其进行基准测试!
关于elixir - Elixir 中的快速不区分大小写排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51787410/