高级字符串处理






4.60/5 (5投票s)
关于字符串处理的高级文章
引言
如今,在编写 Windows 软件,特别是商业应用程序时,有一个领域可能会导致代码执行速度出现真正的瓶颈,甚至在实现上也会如此。
这就是字符串处理领域!
我不是指大多数应用程序中的简单字符串处理,而是指当您需要快速处理大量字符串数据(例如,来自文件)时,同时对字符串数据进行一些复杂的解析。
字符串数据也并非仅仅意味着文本字符。它可能是大量以二进制格式表示的数据,需要被当作一个大字符串来处理。
假设您常用的编程语言在处理某些复杂的字符串数据操作时,在特定情况下表现不佳。您决定使用另一种编程语言编写一个 DLL,而您的当前编程语言可以调用它。您也需要速度!
虽然有很多编程语言可能符合要求,但让我们来看其中一种,它可能为您提供更广泛的工具集,以达到您想要的效果。
Powerbasic (参见:http://powerbasic.com)。
从未听说过?
没关系。我不会详细介绍这款编译器的悠久历史,但您听说过 Turbo Basic 吗?长话短说,Powerbasic 是著名的 TurboBasic 的“孙子”,但它是一款真正的 Windows 32 位编译器。
有几个原因值得认真考虑使用这款编译器来编写 DLL,以便与您当前的编程语言应用程序进行接口。
- 它是 BASIC,并且遵循微软 Basic 语法标准。任何人都可以使用它。
- 它专为最佳速度而设计,那里的开发人员(我不为 Powerbasic 工作)是英特尔机器语言专家,他们热衷于计算 CPU 周期。
- 它具有真正的可变长度原生字符串数据类型,可以存储海量数据在一个字符串中。
注意:Powerbasic 字符串数据类型使用 Windows 中的 OLE 引擎进行数据存储,而不是像其他语言那样使用空终止符。这允许您在字符串中存储任何字节值(包括零),并且它是真正可变长度的。Powerbasic 还提供其他有用的字符串格式,如定长字符串、AsciiZ 字符串(空终止)。
现在,事情变得有趣了。我在使用这款编译器方面有十多年的实际经验,所以我知道它在字符串处理方面能做什么。
以下是一些在其他语言中不常发现的字符串函数列表,其中一些可能除了 Powerbasic 之外在任何其他编译器中都不存在(这就是它能解决问题的所在)。
当然,它支持标准的字符串函数,如 ASC、MID$、SPACE$、LEFT$、RIGHT$、INSTR、TRIM$、LTRIM$、RTRIM$。
但真正被大量使用的是更高级的字符串函数。
那么,假设您拥有这款编译器并想深入研究字符串处理。您从哪里开始?
以下是我的最爱,也是我经常使用的函数:
ARRAY SCAN
它的用法如下
ARRAY SCAN MyData$(1), =SomeString$ , TO Match&
(还有许多其他有用的 ARRAY 命令可用于字符串,如 ARRAY SORT,它们也速度极快。)
此命令允许您在字符串数组中搜索匹配的字符串,而且速度非常快,我指的是真正的快。
PEEK$
此函数可以通过地址指针读取一块数据并返回一个字符串。
PARSE$
我一直使用这个函数,它非常强大,可以将字符串拆分成可变长度的记录。例如,假设您使用逗号 (,) 作为记录分隔符,您可以像这样处理一个字符串:
CT&=PARSECOUNT(BigString$, ",")
FOR I&=1 TO CT&
SmallString$=PARSE$(BigString$,",", I&)
NEXT I&
还有什么比这更简单、更快的呢!
REMOVE$
我经常使用这个函数。
例如,假设您有一个文件,它可能使用回车符作为行尾,也可能使用回车符加换行符。您不知道文件是以哪种方式结尾的,但需要同时解析。您会怎么做?
像这样
BigString$ = REMOVE$(BigString$, CHR$(10) ' remove line feeds
CT&=PARSECOUNT(BigString$, CHR$(13))
FOR I&=1 TO CT&
SmallString$=PARSE$(BigString$,CHR$(13), I&)
NEXT I&
REPLACE
这个命令也是我的最爱。现在,假设您有一个奇怪的文件格式,它使用了一个不寻常的行尾字符。您想要一个回车符。很简单。就这样做:
REPLACE StrangeCharacter$ WITH CHR$(13) in BigString$
现在您可以遍历字符串并解析出数据。
这并非 PowerBasic 中字符串函数/命令的详尽列表,但可以肯定地说,它是最适合字符串处理的语言之一。
现在,事情变得非常有趣了。
尽管它的速度很快(编译器),但我有时仍然觉得不够快。我需要优化的速度,但我不是机器语言程序员(或汇编)。那我该怎么办?
指针!
是的,您甚至可以在可变长度字符串的字符串数据中使用指针。
您可以将字符串中的数据视为字节(或 ASCII 字符),并使用指针以闪电般的速度在字符串中移动,如下所示:
LOCAL B AS BYTE PTR
L&=LEN(BigString$)
B=STRPTR(BigString$) ' get a pointer to start of string
FOR I&=1 TO L&
Test&=@B ' access data via pointer as a byte
INCR B ' increment pointer 1 byte
NEXT I&
现在,您不再仅限于仅以字节形式访问字符串。
假设您有一个包含 1000 个单精度浮点数(SINGLE)的字符串。每个数字(二进制)占用四个字节。我可以像处理二进制浮点数一样遍历字符串,如下所示:
LOCAL S AS SINGLE PTR
L&=LEN(BigString$)/4 ' four bytes per Single floating point number
S=STRPTR(BigString$) ' get a pointer to start of string
FOR I&=1 TO L&
Test!=@S ' access data via pointer as a singles
INCR S ' increment pointer 4 bytes
NEXT I&
现在,您甚至可以使用指针将一个大字符串视为多种数据类型。
在极少数情况下,如果您确实需要最大速度,这款编译器甚至允许您使用内联汇编。因此,如果您的公司有汇编专家,您可以让他们编写对速度要求高的代码,而您编写其余部分。
这款编译器丰富的字符串命令集,加上通过指针处理数据的能力,使其成为您在应用程序中需要最佳字符串处理时的强大工具。而且,最妙的是您不必切换编程语言。只需使用 Powerbasic 编写对速度要求高的字符串处理代码,将其编译为 DLL,然后在对速度要求高的区域调用该 DLL。
这会有多大区别?
您试过才知道,但我读过一些程序员的经验,仅仅通过使用这款编译器处理对速度要求高的字符串代码,就获得了 10 倍甚至更高的速度提升。
历史
- 2010 年 6 月 27 日:首次发布