<Perl算法小菜>排序加速--Schwatzian变换及Guttman-Rosler变换
原创博客,转载请联系博主!
perl里的数据都是以双精度为单元存储的,也就是相当于C/Cpp中的double型,而正则的解析是由perl内置的正则引擎完成的,那么除了重写一个属于自己的排序方法之外,我们应该怎么做才能加速perl内置的sort方法呢,在下文中你将学到两种前沿的hack级perl排序:
(下面示例中将用到的数据的产生方法如下所示)
my $cnt=0;
my @arr;
while($cnt<1000000){
my $key=rand(100000);
my $val=rand(100000);
my $tmp=$key."#".$val;
push @arr,$tmp;
#print $tmp."\n";
$cnt++;
}
(1)Schwatzian变换:
使用能起到加速作用的最佳条件:
1. sort比较代码块中要进行正则匹配捕获
2. sort比较代码块中要进行解/取引用的操作(尤其是解引用)
Schwatzian变换的加速思路是将可能会重置重叠进行的正则匹配捕获操作和对象的解和取操作,提前使用一次map完成,并且将捕获的结果放入一个匿名数组/哈希引用之中,那么在sort的比较块中我们需要做的就是直接在这个匿名数组/哈希中取出提前捕获好的待比较的数据。示例如下所示:
my @sorted2=map{$_->[0]} sort{$a->[1]<=>$b->[1]} map{$_=~/\d+.(\d+)/;[$_,$1];}@arr;
(2) Guttman-Rosler变换
使用能起到加速作用的最佳条件:
1.sort比较代码中要比较的数据长度越长加速效果越明显
Guttman-Rosler变换的思路是用perl中一个特殊的方法pack/unpack,之所以说它特殊,是因为pack/unpack方法是直接由二进制C代码完成的,避开了可能会导致代码速度减慢的perl引擎的数据处理过程。首先具体看一下perl中pack/unpack方法的文档:
Pack 与unpack使用说明: pack可视为将一系列的片段的数值打包在一起,可用于对dev档案、socket、memory的读写,因为这些需要一块完整的memory,而且需要事先打包成特定格式,而unpack可以视为将将这些完整的 memory切割计算,取得我们所需要各部分的Variable。
用法:
pack/unpack “format_def_str” , "original_str"
返回值: 正常是一个标量代表一个pack/unpack后的产生的数据
其中的格式化串的写法/语法如下:
C char
d double
f float
i int
I unsigned int (or unsigned)
l long
L unsigned long
s short
S unsigned short
a : 用空字符(null)补足的字符串
A : 用空格补足的字符串
b : 位串,低位在前
B : 位串,高位在前
c : 带符号字符(通常-128~127)
C : 无符号字符(通常8位)
d : 双精度浮点数
f : 单精度浮点数
h : 十六进制数串,低位在前
H : 十六进制数串,高位在前
i : 带符号整数
I : 无符号整数
l : 带符号长整数
L : 无符号长整数
n : 网络序短整数
N : 网络序长整数
p : 字符串指针
s : 带符号短整数
S : 无符号短整数
u : 转化成uuencode格式
v : VAX序短整数
V : VAX序长整数
x : 一个空字节
X : 回退一个字节
@ : 以空字节(null)填充
首先来看一下perl中Guttman-Rosler变换的示例代码:
my @sorted3=map{ substr $_,4 } sort map { $_=~/\d+#(\d+)/; pack("A*").$_; } @arr;
这一段代码的作用是这样的,首先将原本数组中的每一个元素都用pack打包成pack后的格式,之后用一个连缀符“.” 将格式化后的串和原本字符串连接起来,之后的sort的比较代码块忽略不写(也不能写,哪怕是$a<=>$b也会报fetal error),至于这一块sort比较块不写的原因我真的也就不清楚了,所以说是hack级的写法,这样排序完之后再取出来连接在后面的原本字符串就完成了整个排序的过程!
那么排序的加速结果究竟怎么样呢?我测试的结果是这样的:

其中Schwartzian变换的加速效果会有较大程度的波动,但是Guttman-Rosler变换的加速效果大概稳定在5~20倍左右,所以我更推荐后者!
<Perl算法小菜>排序加速--Schwatzian变换及Guttman-Rosler变换的更多相关文章
- [C#][算法] 用菜鸟的思维学习算法 -- 马桶排序、冒泡排序和快速排序
用菜鸟的思维学习算法 -- 马桶排序.冒泡排序和快速排序 [博主]反骨仔 [来源]http://www.cnblogs.com/liqingwen/p/4994261.html 目录 马桶排序(令人 ...
- javascript数据结构与算法--高级排序算法
javascript数据结构与算法--高级排序算法 高级排序算法是处理大型数据集的最高效排序算法,它是处理的数据集可以达到上百万个元素,而不仅仅是几百个或者几千个.现在我们来学习下2种高级排序算法-- ...
- 经典排序算法 - 高速排序Quick sort
经典排序算法 - 高速排序Quick sort 原理,通过一趟扫描将要排序的数据切割成独立的两部分,当中一部分的全部数据都比另外一部分的全部数据都要小,然后再按此方法对这两部分数据分别进行高速排序,整 ...
- AOV网络和Kahn算法拓扑排序
1.AOV与DAG 活动网络可以用来描述生产计划.施工过程.生产流程.程序流程等工程中各子工程的安排问题. 一般一个工程可以分成若干个子工程,这些子工程称为活动(Activity).完成了这些活动 ...
- 在Object-C中学习数据结构与算法之排序算法
笔者在学习数据结构与算法时,尝试着将排序算法以动画的形式呈现出来更加方便理解记忆,本文配合Demo 在Object-C中学习数据结构与算法之排序算法阅读更佳. 目录 选择排序 冒泡排序 插入排序 快速 ...
- c/c++ 通用的(泛型)算法 之 只读算法,写算法,排序算法
通用的(泛型)算法 之 只读算法,写算法,排序算法 只读算法: 函数名 功能描述 accumulate 求容器里元素的和 equal 比较2个容器里的元素 写算法 函数名 功能描述 fill 用给定值 ...
- 排序算法--希尔排序(Shell Sort)_C#程序实现
排序算法--希尔排序(Shell Sort)_C#程序实现 排序(Sort)是计算机程序设计中的一种重要操作,也是日常生活中经常遇到的问题.例如,字典中的单词是以字母的顺序排列,否则,使用起来非常困难 ...
- 排序算法--选择排序(Selection Sort)_C#程序实现
排序算法--选择排序(Selection Sort)_C#程序实现 排序(Sort)是计算机程序设计中的一种重要操作,也是日常生活中经常遇到的问题.例如,字典中的单词是以字母的顺序排列,否则,使用起来 ...
- javascript数据结构与算法--高级排序算法(快速排序法,希尔排序法)
javascript数据结构与算法--高级排序算法(快速排序法,希尔排序法) 一.快速排序算法 /* * 这个函数首先检查数组的长度是否为0.如果是,那么这个数组就不需要任何排序,函数直接返回. * ...
随机推荐
- appium 学习和环境搭建
官方网站: http://appium.io/ 1.安装各大开发环境:Nodejs. python .java 和 android 环境,并且配置环境变量. ✔ The Node.js binary ...
- Atitit.dart语言的特性 编译时js语言大总结
Atitit.dart语言的特性 编译时js语言大总结 1. 原型环境1 1.1. Dart可以编译js3 2. 第二个期待的理由是Dart的语言特性,没有什么特别特性好像,类似java c#一小时 ...
- EXTjs+SpringMVC+Mybatis实现照片的上传,下载,查看关键技术整理
第一个问题:如何通过Extjs4实现照片上传的布局展示以及本地照片选择后的在一个区域内进行图片预览 实现照片上传的布局展示: items : [ { xtype : 'box', itemId : ' ...
- Log4J 基本使用
Log4j由三个重要的组件 构 成:日志 信息 的优先级,日志信息的输出目的地,日志信息的输出格式. 日志信息的优先级 从高到低有ERROR . WARN . INFO . DEBUG ,分别用来指定 ...
- openWRT自学计划安排
目标:充分理解openwrt的框架构成,能够在openwrt框架下实现:开发新程序,修改现有程序,修改内核,修改boot.为此,制定如下计划: 一.如何在openwrt上做开发 1.编译出一个BRCM ...
- excel批量取消隐藏工作表
按下"Alt+F11"键,在打开的"Microsoft Bisual Basic"窗口中,选择"插入——模块".,复制下面的代码,按F5键运 ...
- 线性判别函数-Fisher 线性判别
这是我在上模式识别课程时的内容,也有参考这里. 线性判别函数的基本概念 判别函数为线性的情况的一般表达式 式中x是d 维特征向量,又称样本向量, 称为权向量, 分别表示为 是个常数,称为阈值权. 设样 ...
- java代码实现目录结构
今天用java代码来实现.像我们电脑盘符那样的目录结构.在代码开始之前首先.介绍一下.用.java代码实现目录的思想. 第一步:完成基础的.大家想.我们是如何获取文件的.是不是用File类,直接就获取 ...
- 通过Lock对象以及Condition对象实现多线程同步
通过Lock对象以及Condition对象实现多线程同步: 在之前的学习中,无论是通过synchronized建立同步代码块,还是通过synchronized建立同步函数,都是把对象看成一把锁来实现同 ...
- Github上好的Android开源框架
1.volley 项目地址 https://github.com/smanikandan14/Volley-demo (1) JSON,图像等的异步下载: (2) 网络请求的排序(scheduli ...