在我开发的过程中,3(2维)数组的串联在其当前版本中占用了大约30%的处理时间。我已经从许多不同的方法中完成了任务(例如,典型的串联与&,join函数也很慢等)。我当前的代码版本如下:
h1 = R21a: R11 = 0
For k1 = 0 To i2
For k2 = 0 To i1
R11 = R11 + 1
If A(k1, k2) = "1" Then Mid$(h1, R11, 1) = "1"
If b1(k1, k2) = "1" Then Mid$(h1, R11 + R12a, 1) = "1"
If b2(k1, k2) = "1" Then Mid$(h1, R11 + R13a, 1) = "1"
Next
Next
在=的左边使用Mid $已被证明是最快的方法,因为我在代码的开头已经完整地初始化了字符串(h1)。 我的目标是将一个字符串中的所有3个数组连接起来,一个接一个。 从我在网上搜索,似乎最快的方法是使用copymemory。但我无法找到解决方法,因为我没有API使用经验。任何带有实用指导的提示或页面对我都非常有帮助。或者,快速完成任何其他方式。
由于我没有停下来试验,因为我发布了上述问题,出现了一个解决方法,我想分享它。我简直不敢相信这种解决方法是如此之快,所以我做了一些时间安排。 现在运行的代码如下(两个部分在同一个进程中一个接一个地运行):
' Existing solution.
GTCs1 = GetTickCount()
h1 = R21a: R11 = 0
For k1 = 0 To i2: For k2 = 0 To i1: R11 = R11 + 1
If A(k1, k2) = "1" Then Mid$(h1, R11, 1) = "1"
If b1(k1, k2) = "1" Then Mid$(h1, R11 + R12a, 1) = "1"
If b2(k1, k2) = "1" Then Mid$(h1, R11 + R13a, 1) = "1"
Next: Next
GTCf1 = GetTickCount(): GTCt1 = GTCt1 + (GTCf1 - GTCs1): GTCc1 = GTCc1 + 1
' Today's workaround ...
GTCs2 = GetTickCount()
Put #44, 1, A(): Get #44, 1, HshStr1
Put #44, 2, b1(): Get #44, 2, HshStr2
Put #44, 3, b2(): Get #44, 3, HshStr3: HshStr = HshStr1 & HshStr2 & HshStr3
GTCf2 = GetTickCount(): GTCt2 = GTCt2 + (GTCf2 - GTCs2): GTCc2 = GTCc2 + 1
对于现有解决方案,代码的每个部分的计时为0,0003526,对于变通方法,计时为0,0000855。计时代码平均重复100,000次,解决方法只需要现有解决方案所需时间的25%。 因此,“Put”可以毫无困难地连接字符串数组。但是,不要只针对静态数组。对于动态数组,它是不一样的。所有信息都在VBA在线文档中。
答案 0 :(得分:1)
CopyMemory允许您复制连续的内存范围。
VBA中的数组作为SAFEARRAY结构存储在内存中。
字符串(可变长度,固定长度字符串的工作方式不同)在内存中存储为BSTR结构。
您还可以在VBA中使用VarPtr,StrPtr和ObjPtr等函数,这些函数可用于获取与外部API(如CopyMemory)一起使用的指针。 StrPtr为您提供指向包含字符串字符串数据的实际缓冲区的指针。
为了给出更明确的答案,我们需要有关变量的更多信息。您没有提供诸如数组之类的信息,如果它们是固定长度,可变长度,变量数组,类型数组......您还没有提供有关目标字符串缓冲区h1由何种组成的信息。它是一个预先分配到所需长度或固定长度字符串的可变长度字符串吗?
尽管如此,只有某些条件才可行。如果您的数组包含一系列字符,并且每个字符都是BSTR中的两个字节,您可以使用CopyMemory将这些字符数组中的连续区域复制到预分配的字符串中,并加快操作速度。但是,如果您的数组是一个字符串数组,这将不起作用。如果它是Variants数组,这将无效。