您现在的位置:新闻首页>论文

Python 再牛,在字符串排序上还是被 Julia 和 R 碾压

2018-12-05 15:32编辑:AI发烧友人气:


  我们简单介绍了 Julia 的背景,以及通过优化一个似然函数的参数 μ 和 σ,来对比 Julia、R、Python三门语言,谁更快,谁的输出更舒适。

  当单个字符串的数量接近数字字符串时,Julia 是最快的,用了 Numpy 排序的 Python 第二,R 最慢。

  而当存在大量重复值(或者如果单一字符串与字符串的比例很小,例如1:100)并且如果存在大数元素,R 是最快的。

  但如果要排序的数字元素很小(例如1000万),Julia 有时会比 R 更快,即使有很多重复项。

  R 使用的是一种字符串驻留形式,理论上讲,这种方法需要更多的安装时间。Julia 默认没有字符串驻留,因此无法执行 R 使用开箱即用的优化。

  能够快速排序字符串是现代数据操作的关键支柱。虽然我们承认对字符串向量进行排序时,真正想要的其实是分组,但是能够快速排序字符串仍然很有价值。

  然而,最初的调查显示,在对具有大量重复值的字符串进行排序时,与 R 相比,Julia 中的字符串排序较慢。

  这可能是通过 R 将 Julia 与 C 进行比较,但从用户的角度来看,直言不讳地说,他们可能并不关心。

  此外,Python 也很慢(参见上面的基准测试),希望 pandas2 可以帮助解决这个问题 。

  但是我觉得,这只是明确地证实 Julia 生态系统目前还不完善,而并不能因此认为 Julia 一定就慢,一定就比不过 R。

  考虑到这一点,我想调研 Julia 进行字符串排序的速度,能否和 R 并驾齐驱,至少能够接近 R 在字符串排序中的表现。

  经过一些研究后,我发现 R 使用基数排序对字符串进行排序,因此是字符串基数排序的 Julia 实现就是顺理成章的事。

  此外,对于已在 SortingAlgorithms.jl 中实现的某些位类型(但不是字符串),存在 LSD 基数排序。 所以我已经实现了 MSD 和 LSD 变种的基数排序算法。

  要执行基数排序,需要访问基础字节。 在字符串中加载第 n 个字符的字节的一种方法是通过代码单元codeunit(s, n) 。例如:

  但是根据我的计算,这个会很慢,赶不上 R。Python 再牛,在字符串排序经过多次实验,上还是被 Julia 和 R 碾压我发现一次加载8个字节几乎与加载1个字节一样快,因此这成了我的首选方法。

  短于8字节的时候,我们需要特别小心。如果无论如何都加载8个字节,并将不需要的位设置为0,我的经验来看大部分情况下是可行的。

  但仍然可能导致尝试访问程序不可用的内存并导致崩溃。目前解决它的方法是测试长度是否短于8个字节,然后使用较慢的加载器。

  而一般出现崩溃的情况,都是发生在跨页面边界加载数据的时候。要搞清楚到底什么时候程序会崩溃,需要了解内存的加载方式。我的理解是:

  如果字符串超过8个字节,可以一次迭代地对字符串向量进行8字节排序。 在基数排序的 MSD 和 LSD 变体中都有很多方法,在此不再赘述。

  但是还需要同时置换原始的字符串向量。为此,我编写了 sorttwo!(bytesvec, stringvec) 函数,用来给字节向量 bytesvec 进行排序,并以在排序过程中置换 bytesvec 相同的方式置换字符串向量。

  我已经实现了 MSD 和 LSD 变量。 根据我的研究,通常情况是 MSD 算法对于可变长度字符串支持更好,并且 LSD 算法对固定长度算法最有效。

  有些人甚至声称 LSD 不适用于可变长度字符串向量。 我认为这不正确,因为你可以用0表示一个空字节(即使技术上是 null)。

  例如,如果我使用8字节加载器加载字符串“abc”,则它变为十六进制格式,0x0 其中 6162 和 63 是 ASCII 码“a”,“b”和“c”十六进制表示形式。

  从我的基准测试来看,即使对于可变长度字符串,我的 MSD 实现也不像 LSD 算法那样高效,这就有点奇怪了。

  因为我的大多数研究都认为 MSD 比 LSD 更具性能。这可能表明我对 MSD 基数排序的实现不是最理想的。

  许多人指出 R 使用一种字符串驻留来存储其字符串。我对其工作原理的理解是这样的:例如,考虑a = c("abcdefghi", "abcdefghi") 是包含相同内容的两个字符串的向量,因此a[1]和a[2]只指向“abcdefghi”的一个存储空间,而不是存储相同字符串的两个副本。

  如果相同的字符串仅存储一次,很显然是可以提高空间效率。此外,更重要的是,人们能够利用它来制作更高性能的算法。

  此外,这有可能简化分组操作。如果用户知道具有相同内容的所有字符串具有相同的指针,那么我们可以直接给固定大小的指针进行分组,从而可以更快地进行排序和分组。

  但是,Julia 默认没有驻留的字符串(虽然有一个包InternedStrings.jl),因此这些类型的优化并不容易获得,导致 Julia 可能很难在所有情况下匹配 R 的字符串排序性能。

  这确实开辟了另一种看待事物的方式:R 需要更长的时间来加载这些字符串,因为它们还需要将它加载到全局缓存中;加载时间越长,分拣速度越快。

  那么,Julia 就可能会创建一个模仿 R 行为并导致更高性能排序的数据结构。所以尽管现在 R 是最快,未来还真不好说。

  有研究论文表明,最有效加快排序算法速度的方法,就是并行技术,因此我对 MSD 字符串基数排序的实现可能不是最优解。

  其实无论是人,人工智能咨询机器,搜狗穿越“AI”险境,算法,追求的都是更快、更高、更强。不断地发现极限,不断地突破极限,不断有新技术、新算法被创造出来。我们向着星辰大海,不断的前进。

  这篇文章更准确的说,是作者做基准测试时候的一些随笔,而不是一个教程,所以中间省去了很多解释的环节,直接上来就是思路和结论。

(来源:未知)

织梦二维码生成器
已推荐
0
  • 凡本网注明"来源:的所有作品,版权均属于中,转载请必须注明中,http://www.ai278.com。违反者本网将追究相关法律责任。
  • 本网转载并注明自其它来源的作品,目的在于传递更多信息,并不代表本网赞同其观点或证实其内容的真实性,不承担此类作品侵权行为的直接责任及连带责任。其他媒体、网站或个人从本网转载时,必须保留本网注明的作品来源,并自负版权等法律责任。
  • 如涉及作品内容、版权等问题,请在作品发表之日起一周内与本网联系,否则视为放弃相关权利。






图说新闻

更多>>
旷视科技提出新型端到端可训练网络Mask TextSpot

旷视科技提出新型端到端可训练网络Mask TextSpot



返回首页