0

背景

这是一个优化问题。Oracle Forms XML 文件具有以下元素:

<Trigger TriggerName="name" TriggerText="SELECT * FROM DUAL" ... />

其中TriggerText是任意 SQL 代码。每个 SQL 语句都被提取到唯一命名的文件中,例如:

sql/module=DIAL_ACCESS+trigger=KEY-LISTVAL+filename=d_access.fmb.sql     
sql/module=REP_PAT_SEEN+trigger=KEY-LISTVAL+filename=rep_pat_seen.fmb.sql 

我编写了一个脚本来使用蛮力方法生成一个完全重复的列表。

问题

有 37,497 个文件可供相互比较;将一个文件与所有其他文件进行比较需要 8 分钟。从逻辑上讲,如果A = BA = C,则不需要检查 if B = C。所以问题是:如何消除冗余比较?

该脚本将在大约 208 天内完成。

脚本源代码

比较脚本如下:

#!/bin/bash

echo Loading directory ...

for i in $(find sql/ -type f -name \*.sql); do
        echo Comparing $i ...

        for j in $(find sql/ -type f -name \*.sql); do
                if [ "$i" = "$j" ]; then
                        continue;
                fi

                # Case insensitive compare, ignore spaces
                diff -IEbwBaq $i $j > /dev/null

                # 0 = no difference (i.e., duplicate code)
                if [ $? = 0 ]; then
                        echo $i :: $j >> clones.txt
                fi
        done
done

问题

您将如何优化脚本以便检查克隆代码的速度提高几个数量级?

想法#1

将匹配的文件删除到另一个目录中,这样就不需要检查两次。

系统约束

使用带有 SSD 的四核 CPU;尽可能避免使用云服务。该系统是安装了 Cygwin 的基于 Windows 的机器——欢迎使用其他语言的算法或解决方案。

谢谢!

4

3 回答 3

1

您的解决方案和 sputnick 的解决方案都需要 O(n^2) 时间。这可以通过对文件进行排序并使用列表合并在 O(nlog n) 时间内完成。它可以通过比较文件的 MD5(或任何其他加密强的哈希函数)而不是文件本身来进一步加快速度。

假设您在sql目录中:

md5sum * | sort > ../md5sums
perl -lane 'print if $F[0] eq $lastMd5; $last = $_; $lastMd5 = $F[0]' < ../md5sums

使用上面的代码将只报告精确的逐字节重复。如果您想考虑两个不相同的文件在此比较中是等效的(例如,如果您不关心大小写),请首先创建每个文件的规范化副本(例如,通过将每个字符转换为小写tr A-Z a-z < infile > outfile) .

于 2012-10-23T05:17:45.110 回答
0

最好的方法是散列每个文件,比如 SHA-1,然后使用一个集合。我不确定 bash 可以做到这一点,但 python 可以。虽然如果你想要最好的性能 C++ 是要走的路。

于 2012-10-23T05:22:33.067 回答
-1

要优化文件比较:

#!/bin/bash

for i; do
    for j; do
        [[ "$i" != "$j" ]] &&
            if diff -IEbwBaq "$i" "$j" > /dev/null; then
                echo "$i & $j are the same"
            else
                echo "$i & $j are different"
            fi
    done
done

用法

./script /dir/*
于 2012-10-23T01:47:44.700 回答