elixir - Elixir 中的快速不区分大小写排序

标签 elixir

嗨,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/

相关文章:

elixir - Turbolinks,:remote forms and links in Phoenix?

testing - 有在线 Elixir IDE 吗?

elixir - Ecto NoSQL 适配器的最低要求

elixir - 使用带有子查询的 Ecto 进行预加载并使用主查询中的联接

testing - 如何在不同于 lib (Elixir) 的路径中加载文件

unit-testing - ExUnit - 运行存储在自定义目录中的所有测试(不是测试/)

elixir - 编译错误phoenix_ecto

postgresql - 如何删除 ecto Elixir 中的主键列

elixir - 从 version1.3 开始有没有更好的方法用 Elixir 编写条件结构

pattern-matching - 使用模式匹配检查偶数长度