Perl中著名的Schwartzian转换问题解决实现


Posted in Python onJune 02, 2015

Perl中著名的Schwartzian转换,其产生背景主要涉及到排序问题:
比如说,根据文件名以字母顺序排序,代码如下:

use strict;  

use warnings;  

   

my @files = glob "*.xml";          #perl中文件操作符glob提供相当于shell中的通配符的功能  

my @sorted_files = sort @files;    #sort(),排序,默认是字母顺序排序

比如说,根据文件名长度排序,其代码如下:
use strict;  

use warnings;  

  

#length求长度。 太空船操作符<=>,默认变量是$a,$b,返回值为-1,0,1分别表示大于,==,小于。 sort进行排序  

my $files = ".xml";  

my @sorted_length = sort { length($a) <=> length($b) } @files; 

上面的两种情况,对很多文件操作来说,速度还不算慢,如果是下面这种情况。
比如说:要批量比较文件大小,其代码如下:
use strict;  

use warnings;  

   

my @files     = glob "*.xml";     

my @sort_size = sort { -s $a <=> -s $b } @files;  #比较大小 

上面的代码设计到三重(次)操作:
1. 从硬盘上获取文件大小(-s $b)
2. 比较文件大小(太空船操作)
3. 对其进行排序(sort操作)
考虑到要比较$a,$b大小时,要从硬盘中获取两次,所以次数是6次!也就是说,如果有1万个文件,总共是6万次。
其算法复杂度是: n*long(n),考虑到后两项(比较文件大小,进行排序)必然要进行的操作,但第一项却可以降低!
即一次性从硬盘中读取所有文件大小,将其放置到Perl中的默认的变量,并存储到内存中!于是又下面算法实现:
use strict;  

use warnings;  

  

my @files = glob "*.xml";  

  

my @unsorted_pairs = map  { [$_, -s $_] } @files;  

my @sorted_pairs   = sort { $a->[1] <=> $b->[1] } @unsorted_pairs;  

my @sorted_files   = map  { $_->[0] } @sorted_pairs; 

看上去比较复杂,分三个步骤解释下:
第一步:遍历文件列表,对每个文件创建一个数组引用。数组引用包含两个元素:
       第一个是文件名($_),第二个是文件大小(-s $_)。这样,处理每个文件只访问一次磁盘。
第二步:对二维数组排序。因比较文件大小,所以需取元素[1],比较它们的值。得到另一个二维数组。
第三步:丢掉文件大小元素,创建一个只含文件名的列表。完成目标!
上面的代码使用了两个临时数组,但这并不是必须的。我们可以一个语句就能完成所有的工作。为了达到目的,需要按照“数据从右流向左”的原理反转句子顺序,不如果将每个句子放在单独一行,并且留出足够的空间,我们依然可以写出可读性高的代码。
my @quickly_sorted_files =  

    map  { $_->[0] }  

    sort { $a->[1] <=> $b->[1] }  

    map  { [$_, -s $_] }  

    @files; 

这就是以Randal L. Schwartz命名的Schwartzian转换,对数据量特多的情况下,其速度要比前者快数倍!
下面写了小程序,包括在生成1万个xml文件,在两种情况下,完整代码如下:
#!/usr/bin/perl -w  

use strict;  

use warnings;  

use autodie;  

use v5.10;  

  

######################################  

###  创建要比较的10,000个.xml文件 ###  

######################################  

my $profix = ".xml";  

  

foreach my $num (1..10000) {  

    open(my $fh, '>', $num . $profix) || die "Can not create the file: $!\n";  

    print $fh "This is file size testing!";  

}  

  

print "All the 10_1000 files created! \n";  

  

  

######################################  

### 常规转换:      遍历20次       ###  

######################################  

my $t1  = time();  

  

foreach (1..20){   

    my @files     = glob "*.xml";  

    my @sorted    = sort { -s $a <=> -s $b } @files;  

}  

  

say "常规算法需要时间: => ", time()- $t1;  

  

  

######################################  

### Schwartzian转换: 遍历20次     ###  

######################################  

my $t2  = time();  

  

foreach (1..20){   

    my @files = glob "*.xml";  

        my @sorted =   

            map  {$_->[0]}  

            sort {$a->[1] <=> $b->[1]}  

            map  {[$_, -s $_]}  

       @files;  

} 
say "Schwartzian算法需要时间: => ", time()- $t2; 

输出结果:
All the 10_1000 files created!
常规算法需要时间:          => 185
Schwartzian算法需要时间: => 115

Python 相关文章推荐
Python中属性和描述符的正确使用
Aug 23 Python
python中快速进行多个字符替换的方法小结
Dec 15 Python
Python简单实现的代理服务器端口映射功能示例
Apr 08 Python
Selenium鼠标与键盘事件常用操作方法示例
Aug 13 Python
Python版名片管理系统
Nov 30 Python
python实现比对美团接口返回数据和本地mongo数据是否一致示例
Aug 09 Python
django-rest-swagger的优化使用方法
Aug 29 Python
Django之路由层的实现
Sep 09 Python
Python 网络编程之UDP发送接收数据功能示例【基于socket套接字】
Oct 11 Python
PHP基于phpqrcode类库生成二维码过程解析
May 28 Python
python 下载文件的几种方式分享
Apr 07 Python
Python中threading库实现线程锁与释放锁
May 17 Python
python通过ssh-powershell监控windows的方法
Jun 02 #Python
Python lxml模块安装教程
Jun 02 #Python
Python脚本文件打包成可执行文件的方法
Jun 02 #Python
python统计cpu利用率的方法
Jun 02 #Python
Python2.x中文乱码问题解决方法
Jun 02 #Python
python实现的守护进程(Daemon)用法实例
Jun 02 #Python
Python中使用ElementTree解析XML示例
Jun 02 #Python
You might like
PHP OPCode缓存 APC详细介绍
2010/10/12 PHP
destoon文章模块调用企业会员资料的方法
2014/08/22 PHP
PHP变量赋值、代入给JavaScript中的变量
2015/06/29 PHP
PHP simplexml_load_string()函数实例讲解
2019/02/03 PHP
页面加载完毕后滚动条自动滚动一定位置
2014/02/20 Javascript
JavaScript中双叹号(!!)作用示例介绍
2014/04/10 Javascript
js监控IE火狐浏览器关闭、刷新、回退、前进事件
2014/07/23 Javascript
js实现有时间限制消失的图片方法
2015/02/27 Javascript
jQuery获取元素父节点的方法
2016/06/21 Javascript
Bootstrap 模态框(Modal)带参数传值实例
2017/08/20 Javascript
微信小程序 如何保持登录状态
2019/08/16 Javascript
antd-mobile ListView长列表的数据更新遇到的坑
2020/04/08 Javascript
JQuery复选框全选效果如何实现
2020/05/08 jQuery
解决vue使用vant轮播组件swipe + flex时文字抖动问题
2021/01/07 Vue.js
[01:30:54]《加油DOTA》 第三期
2014/08/18 DOTA
[01:45]DOTA2众星出演!DSPL刀塔次级职业联赛宣传片
2014/11/21 DOTA
Python日期操作学习笔记
2008/10/07 Python
Python list操作用法总结
2015/11/10 Python
PYTHON压平嵌套列表的简单实现
2016/06/08 Python
Python探索之创建二叉树
2017/10/25 Python
Python中 传递值 和 传递引用 的区别解析
2018/02/22 Python
python分块读取大数据,避免内存不足的方法
2018/12/10 Python
Python Django搭建网站流程图解
2020/06/13 Python
python线程优先级队列知识点总结
2021/02/28 Python
使用postMessage让 iframe自适应高度的方法示例
2019/10/08 HTML / CSS
英国领先的餐饮折扣俱乐部:Gourmet Society
2020/07/26 全球购物
给同事的道歉信
2014/01/11 职场文书
优秀毕业生事迹材料
2014/02/12 职场文书
军训感想500字
2014/02/20 职场文书
2014最新房贷收入证明范本
2014/09/12 职场文书
单位委托书范本(3篇)
2014/09/18 职场文书
公务员群众路线心得体会
2014/11/03 职场文书
2014幼儿园家长工作总结
2014/11/10 职场文书
庆元旦主持词
2015/07/06 职场文书
十大好看的穿越动漫排名:《瑞克和莫蒂》第一,国漫《有药》在榜
2022/03/18 日漫
游戏《我的世界》澄清Xbox版暂无计划加入光追
2022/04/03 其他游戏