这是一个优化问题。 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 = B
和A = C
,则无需检查是否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
如何优化脚本以便检查克隆代码的速度要快几个数量级呢?
将匹配的文件删除到另一个目录中,这样就不需要对它们进行两次检查。
使用带有SSD的四核CPU;尽可能避免使用云服务。该系统是安装了Cygwin的基于Windows的机器 - 欢迎使用其他语言的算法或解决方案。
谢谢!
答案 0 :(得分: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
使用上面的代码只会报告精确的逐字节重复项。如果您想要将两个不相同的文件视为此比较的等效文件(例如,如果您不关心案例),请首先创建每个文件的规范化副本(例如,通过将每个字符转换为小写字母{ {1}})。
答案 1 :(得分:0)
执行此操作的最佳方法是散列每个文件,如SHA-1,然后使用集合。我不确定bash可以做到这一点,但python可以。虽然如果你想要最佳性能,C ++就是你的选择。
答案 2 :(得分:-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
<强> USAGE 强>
./script /dir/*