65.9K
CodeProject 正在变化。 阅读更多。
Home

高级字符串处理

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.60/5 (5投票s)

2010 年 6 月 27 日

CPOL

5分钟阅读

viewsIcon

18587

关于字符串处理的高级文章

引言

如今,在编写 Windows 软件,特别是商业应用程序时,有一个领域可能会导致代码执行速度出现真正的瓶颈,甚至在实现上也会如此。

这就是字符串处理领域!

我不是指大多数应用程序中的简单字符串处理,而是指当您需要快速处理大量字符串数据(例如,来自文件)时,同时对字符串数据进行一些复杂的解析。

字符串数据也并非仅仅意味着文本字符。它可能是大量以二进制格式表示的数据,需要被当作一个大字符串来处理。

假设您常用的编程语言在处理某些复杂的字符串数据操作时,在特定情况下表现不佳。您决定使用另一种编程语言编写一个 DLL,而您的当前编程语言可以调用它。您也需要速度!

虽然有很多编程语言可能符合要求,但让我们来看其中一种,它可能为您提供更广泛的工具集,以达到您想要的效果。

Powerbasic (参见:http://powerbasic.com)。

从未听说过?

没关系。我不会详细介绍这款编译器的悠久历史,但您听说过 Turbo Basic 吗?长话短说,Powerbasic 是著名的 TurboBasic 的“孙子”,但它是一款真正的 Windows 32 位编译器。

有几个原因值得认真考虑使用这款编译器来编写 DLL,以便与您当前的编程语言应用程序进行接口。

  1. 它是 BASIC,并且遵循微软 Basic 语法标准。任何人都可以使用它。
  2. 它专为最佳速度而设计,那里的开发人员(我不为 Powerbasic 工作)是英特尔机器语言专家,他们热衷于计算 CPU 周期。
  3. 它具有真正的可变长度原生字符串数据类型,可以存储海量数据在一个字符串中。

注意: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 日:首次发布
© . All rights reserved.