嗨其他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
数据结构的一个例子:
[
  %{
    "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必须做工作分配数据结构来存储计算值,但对于这个输入它应该仍然更快.在使用之前,您应该自己仔细测试一下!