想来想去总觉得2#哪里不对劲,今天终于发现了问题所在:添加的contains方法效率极其低下,每个数据都要调用一次contains,每次调用都要for循环遍历,总循环次数成几何级增加。
js改用散列数组代替自定义的contains方法:- var t = (new Date()).getTime();
-
- var out = [], res = [], max = 0;
- var map = [];
- var fso = new ActiveXObject('Scripting.FileSystemObject');
- var objFile = fso.OpenTextFile('a.txt', 1);
-
- while( !objFile.AtEndOfStream ){
- var arrLine = objFile.ReadLine().split('\t'); //按单个Tab字符分割成数组
- var len = arrLine.length;
- for( var i = 0; i < len; i++ ){
- if( out[i] instanceof Array == false ){ //out[i]不是数组类型
- out[i] = []; //初始化
- map[i] = [];
- }else if( map[i][arrLine[i]] ){
- continue; //out[i]去重复
- }
- map[i][arrLine[i]] = true;
- out[i].push(arrLine[i]); //数据放入二维数组
- }
- }
-
- for( var i = 0; i < out.length; i++ ){
- max = max < out[i].length ? out[i].length : max; //求最大行数
- }
-
- for( var i = 0; i < max; i++ ){ //行
- var str = '';
- for( var j = 0; j < out.length; j++ ){ //列
- str += ( out[j][i] == undefined ? '' : out[j][i] ) + '\t';
- }
- res.push(str);
- }
-
- fso.OpenTextFile('b.txt', 2, true).Write( res.join('\r\n') );
-
- WSH.Echo((new Date()).getTime() - t);
复制代码 PowerShell改用HashTable containsKey方法代替数组IndexOf方法:- $t = get-Date;
- $srcFile = 'a.txt'; #修改前的文件名
- $dstFile = 'b.txt'; #修改后的文件名
-
- $out = [Collections.ArrayList]@(); #数组,存放行、列数据
- $ret = [Collections.ArrayList]@(); #数组,返回处理结果
- $map = [Collections.ArrayList]@(); #数组,存放HashTable
- $max = 0; #最大行数
-
- forEach( $strLine In [IO.File]::ReadAllLines($srcFile) ){
- $arrLine = $strLine.Split("`t"); #按单个Tab字符分割成数组
- for( $i=0; $i -lt $arrLine.Count; $i++ ){
- if( $out[$i] -isNot [Collections.ArrayList] ){ #如果$out[$i]不是数组类型
- $null = $out.Add( [Collections.ArrayList]@() ); #数组$out添加$out[$i]
- $null = $map.Add( @{} ); #数组$map添加$map[$i]
- } elseIf( $map[$i].ContainsKey($arrLine[$i]) ){
- continue; #数组$out[$i]去重
- }
- $null = $out[$i].Add( $arrLine[$i] ); #数组$out[$i]存放列数据
- $map[$i].Add( $arrLine[$i], $true ); #添加到HashTable
- }
- }
-
- for( $i=0; $i -lt $out.Count; $i++ ){
- if( $max -lt $out[$i].Count ){ $max = $out[$i].Count; } #计算最大行数
- }
-
- for( $i=0; $i -lt $max; $i++ ){ #遍历行
- $str = '';
- for( $j=0; $j -lt $out.Count; $j++ ){ #遍历列
- $str += $out[$j][$i] + "`t";
- }
- $null = $ret.Add($str); #存放结果
- }
-
- [IO.File]::WriteAllLines($dstFile, $ret); #输出
-
- ((get-Date) - $t).TotalSeconds
- [Console]::ReadLine();
复制代码 测试10000行10列的文本,两个脚本用时都在 0.5s 以内,基本算是正常了。
生成测试文本:- @echo off
- setlocal enabledelayedexpansion
- (for /L %%i in (1,1,10000) do (
- set "s="
- for /L %%j in (1,1,10) do (
- set /a r = !Random! %% 8000
- set "s=!s!!r! "
- )
- echo;!s:~0,-1!
- )) > a.txt
复制代码
|