如何对大文本文件运行字典搜索?
Posted
技术标签:
【中文标题】如何对大文本文件运行字典搜索?【英文标题】:How to run a dictionary search against a large text file? 【发布时间】:2009-05-31 15:27:43 【问题描述】:我们正处于发布主机游戏的最后阶段。当然,在 Wii 上,我们在内存方面遇到的问题最多,所以我们正忙于寻找草率的编码、打包位等等。
我已经完成了内存转储并使用 strings.exe(来自 sysinternals)来分析它,但它会产生很多这样的垃圾:
''''$$$$ %%%%
''''$$$$%%%%####&&&&
''''$$$$((((!!!!$$$$''''((((####%%%%$$$$####((((
''))++.-$$%&''))
'')*>BZf8<S]^kgu[faniwkzgukzkzkz
'',,..EDCCEEONNL
我对这样的字符串更感兴趣:
wood_wide_end.bmp
restroom_stonewall.bmp
...这意味着我们仍在嵌入一些需要转换为 ID 的字符串。
所以我的问题是:有什么好的方法可以找到我们可以消除的可能是我们的调试数据的东西?
我可以做一些 rx 来破解符号或搜索某些类型的字符串。但我真正想做的是获取一个标准字典文件并根据它搜索我的字符串文件。如果我要使用 aardvaark|almony|archetype 等构建一个大 rx,这似乎很慢。或者如果我为它做一个 .NET 编译的 rx 程序集,这是否足够好?
寻找其他关于如何找到我们想要消除的东西的想法。快速而肮脏的解决方案,不需要优雅。谢谢!
【问题讨论】:
内存真的那么紧,需要尝试将“wood_wide_end.bmp”从 20 字节压缩到 4 字节吗?您可以快速分析一下这项工作可能会给您带来多少收益,以及它是否有帮助。 保存单独的 16 个字节是不值得的,真的。但是,如果我们在一个关卡中有 1000 个纹理,并且每个纹理在每个被引用的地方都有一个副本(10K+ 模型),那么我们就在谈论真实内存。我正在尝试使用字符串分析来找到我们可以进行的整个内存优化类。 另外,我们将该 ID 设为 2 字节数字,而不是 4。:) 【参考方案1】:首先,我会得到一个很好的单词列表。 This NPL page 有一个很好的列表,包含不同大小和来源的单词列表。我要做的是为单词列表中的所有单词构建一个哈希表,然后根据单词列表测试strings
输出的每个单词。这在 Python 中很容易做到:
import sys
dictfile = open('your-word-list')
wordlist = frozenset(word.strip() for word in dictfile)
dictfile.close()
for line in sys.stdin:
# if any word in the line is in our list, print out the whole line
for word in line.split():
if word in wordlist:
print line
break
然后像这样使用它:
strings myexecutable.elf | python myscript.py
但是,我认为您将注意力集中在错误的地方。消除调试字符串的收益非常递减。尽管消除调试数据是任天堂要求您执行的技术认证要求,但我认为他们不会因为您的 ELF 中有几个额外的字符串而拒绝您。
使用分析器并尝试确定您使用最多内存的位置。如果您将精力集中在正确的位置,很有可能会有一种方法可以轻松节省大量内存。
【讨论】:
我想这就是我要找的,谢谢。请注意,我们正在寻找内存优化的许多领域。这只是我正在探索的一条路线,因为它很容易。我们上周消除了游戏对象名称,它节省了 100 个 K 的内存。寻找更容易的胜利,但文件中的所有噪音都让它变得困难。 在不了解您的系统的情况下,“因为它很容易”这句话让我想起了一个老笑话,酒鬼在路灯下寻找丢失的钥匙。当有人主动提供帮助并询问钥匙掉在哪里时,醉汉指着街道的另一边,但他在灯光下看,因为这样容易得多。开个玩笑,别太在意。分析将指向键所在的位置。 好笑话,但在这里不适用。出于这个问题的目的,让我们假设我知道自己在做什么,并且在很多游戏中都做过这种事情。我真的很想对字符串的输出进行扫描,作为我们正在研究的大量潜在优化中的一小部分。【参考方案2】:对于支持正则表达式的快速而肮脏的脚本来说,这听起来像是一个理想的任务。如果是我,我可能会很快在 python 中做一些事情。
这是我将如何进行的: 每次遇到字符串(来自 strings.exe 输出)时,提示用户他们是想在字典中记住它还是永久忽略它。如果用户选择永久忽略该字符串,那么以后遇到它时,不要提示用户并丢弃它。您可以选择保留一个反字典文件,以便在以后运行脚本时记住这一点。建立字典文件并为每个字符串保留一个计数或您想要的任何其他信息。可以选择按字符串出现的次数排序,这样您就可以专注于最严重的违规者。
这听起来像是学习脚本语言的理想任务。我不会打扰 C#/C++ 或任何真正花哨的东西来实现它。
【讨论】:
我应该提到 uniq 的字符串输出是多兆的。对于逐个字符串的批准来说太多了。以上是关于如何对大文本文件运行字典搜索?的主要内容,如果未能解决你的问题,请参考以下文章