关于算法:按位而不是字节比较

bitwise not in byte compare

假设我得到这样一个字节:00010001(有2个位)

我想把它与这些字节进行比较:0000 0110,0000 0011,0011 0000,0000 1100_

其思想是获取不匹配的字节;其中(bytea&bytex)=0例如,我应该得到/找到:0000 0110,0000 1100_

如果我们编写一个循环字节数组的代码,这可能很容易。这里有一个例子:

1
2
3
4
5
6
7
8
9
byte seek = 17;
byte[] pool = {6, 3, 48, 12 };
for(int p=0; p<pool.Length; p++)
{
    if((pool[p] & seek)==0)
    {
        //Usefull
    }
}

现在,我希望在不循环数组的情况下执行相同的操作。假设数组很大,我希望将每个字节与其余字节进行比较。

1
2
3
4
5
6
7
8
9
10
for(int p1=0; p1<pool.Length; p1++)
{
    for(int p2=0; p2<pool.Length; p1++)
    {
        if((pool[p1] & pool[p2])==0)
        {
        //byte at p1 works with byte at p2.
        }
    }//for p2
}//for p1

那么我有什么选择呢?字典对我没有帮助(我想),因为如果我的查找字节是0001 0001我要找不到这样的字节:xxx0 xxx0

有什么想法吗?非常感谢你的帮助;

我欢迎C,C++或任何伪代码。我在找一个算法,不需要太多的代码

迈克


一个相当普遍的解决方案是"位转置"您的数据,这样您就有了一个包含所有高阶位数据的字块,一个包含所有位的字块,从那里向下一个位置,等等。然后对于您的两位查询,您或者将两个这样的单词块放在一起并查找0位-因此,如果结果单词是-1,则可以完全跳过它。要查找单词x中所有0位的位置,请查看popcnt(x^(x+1)):如果x=..10111,那么x+1=..11000,那么x^(x+1)=000..01111-popcnt将告诉您最低顺序0在哪里。实际上,最大的胜利可能是当您的大多数数据不满足查询,并且您可以跳过整句话:当您有很多匹配项时,任何方案下的查询成本都可能比您计划对匹配项执行的任何操作的成本都小。在数据库中,这是http://en.wikipedia.org/wiki/bitmap_index-那里有很多信息和指向源代码的指针。

在Knuth第2卷第6.5节-"二进制属性"中有许多关于查询0/1数据的想法。其中大部分要求您了解数据的分布情况,以识别它们的适用位置。其中的一个想法通常是适用的——如果您有任何类型的树结构或索引结构,您可以在树的节点中保存关于或/和它下面的所有内容的信息。然后,您可以根据这些信息检查您的查询,有时您可能会发现该节点下面的任何内容都不可能与您的查询匹配,在这种情况下,您可以全部跳过它。如果位之间存在连接,这可能是最有用的,例如,如果您只是通过对池进行排序并将其切割成块来划分池,即使不影响划分成块的位都是以某些块设置的,而不是以其他块设置的。


这里有一个完全不同的想法,可能工作得很好,也可能工作得不好,这取决于你的游泳池里有什么。

将整个池放入零抑制二进制决策图中。pool中的项将被设置,其中位为1的索引是该集的元素。ZDD是所有这些设备的家族。要进行查询,请形成另一个zdd—不包括seek中1位的所有集合的族(即节点方面的小zdd),然后枚举这些zdd交叉处的所有集合。

从交叉点枚举所有这些集合是一种输出敏感的算法,但是计算交叉点需要时间,这取决于zdd的大小,所以它是否工作良好取决于pool是否是一个好的zdd(查询zdd绝对是好的)。当然,您必须准备好ZDD,所以在任何情况下,只有您计划经常查询同一个池,它才会有所帮助。


字节最大的优点是只有256种可能性。

您可以首先创建一个2d数组256x256,然后用您的两个值对数组进行查找。

您可以先创建数组,然后将结果作为静态实例存储在主程序中。

1
2
3
4
5
6
7
8
9
static bool[256,256] LookUp = {
 {true, true, true ... },
 ...
 {false, false, false ...}
};

static bool IsUsefule(byte a, byte b) {
 return LookUp[a][b];
}
  • 编辑*或者使用答案数组

内部数组将只包含"有用"的字节。

1
2
3
4
5
static List<<byte[]> LookUp = new List<byte[]>(256);

static byte[] IsUseful(byte a) {
 return LookUp[a];
}

如果"a"=0,则isuseful将返回设置了位的255个字节。这将从您的示例中避免您的内部循环。


首先,我的英语很差,但我希望你能理解。另外,我知道我的答案有点晚了,但我认为仍然有用。

正如有人指出的,最好的解决方案是生成一个查找表。为此,您必须将每个循环迭代案例硬编码到一个数组.
幸运的是,我们使用的是字节,因此只能使用256病例。例如,如果我们以您的模式列表3、6、12、48为例,得到这张桌子:

1
2
3
4
5
6
7
8
9
10
11
12
0: { 3, 6, 12, 48 }
1: { 6, 12, 48 }
2: { 12, 48 }
3: { 12, 48 }
3: { 12, 48 }

    ...

252: { 3 }
253:   -
254:   -
255:   -

我们使用输入字节作为查找表中的索引,以获取与输入字节不匹配的列表模式值。
BR/>

实施:

我使用python生成了两个头文件。一个带查找台的定义,另一个具有所需模式列表值的定义。然后,我将这个文件包含在一个新的C项目中,仅此而已!

Python代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#! /usr/bin/env python

from copy import copy
from time import *
import getopt
import sys


class LUPattern:
    __LU_SZ = 256

    BASIC_TYPE_CODE ="const uint8_t"
    BASIC_ID_CODE ="p"
    LU_ID_CODE ="lu"
    LU_HEADER_CODE ="__LUPATTERN_H__"
    LU_SZ_PATTLIST_ID_CODE ="SZ"
    PAT_HEADER_CODE ="__PATTERNLIST_H__"
    PAT_ID_CODE ="patList"


    def __init__(self, patList):
        self.patList = copy(patList)


    def genLU(self):
        lu = []

        pl = list( set(self.patList) )
        pl.sort()

        for i in xrange(LUPattern.__LU_SZ):
            e = []
            for p in pl:
                if (i & p) == 0:
                    e.append(p)
            lu.append(e)

        return lu


    def begCode(self):
        code ="//" + asctime() +"

" \
            +"#ifndef" + LUPattern.LU_HEADER_CODE +"
" \
            +"#define" + LUPattern.LU_HEADER_CODE +"
" \
            +"
#include <stdint.h>

" \

        return code


    def luCode(self):
        lu = self.genLU()
        pDict = {}

        luSrc = LUPattern.BASIC_TYPE_CODE \
            +" * const" \
            + LUPattern.LU_ID_CODE \
            +"[%i] = {
\t" % LUPattern.__LU_SZ

        for i in xrange(LUPattern.__LU_SZ):
            if lu[i]:
                pId ="_%i" * len(lu[i])
                pId = pId % tuple(lu[i])
                pId = LUPattern.BASIC_ID_CODE + pId

                pBody ="{" +"%3i," * len(lu[i]) +" 0 }"
                pBody = pBody % tuple(lu[i])

                pDict[pId] = pBody
                luSrc += pId
            else:
                luSrc +="0"

            luSrc += (i & 3) == 3 and (",
\t") or","

        luSrc +="
};"

        pCode =""
        for pId in pDict.keys():
            pCode += "static" + \
                LUPattern.BASIC_TYPE_CODE + \
               "" + pId +"[] =" + \
                pDict[pId] +";
"

        return (pCode, luSrc)        


    def genCode(self):
        (pCode, luSrc) = self.luCode()
        code = self.begCode() \
            + pCode +"

" \
            + luSrc +"

#endif

"

        return code    


    def patCode(self):
        code ="//" + asctime() +"

" \
            +"#ifndef" + LUPattern.PAT_HEADER_CODE +"
" \
            +"#define" + LUPattern.PAT_HEADER_CODE +"
" \
            +"
#include <stdint.h>

"
        code +="enum {" \
            + LUPattern.LU_SZ_PATTLIST_ID_CODE \
            +" = %i," % len(self.patList) \
            +"};

"
        code +="%s %s[] = {" % ( LUPattern.BASIC_TYPE_CODE,
                                   LUPattern.PAT_ID_CODE )
        for p in self.patList:
            code +="%i," % p
        code +="};

#endif

"


        return code



#########################################################


def msg():
    hmsg ="Usage:"
    hmsg +="%s %s %s"  % (
        sys.argv[0],
       "-p",
       ""{pattern0, pattern1, ... , patternN}"

")
    hmsg +="Options:"

    fmt ="
%5s, %" +"%is" % ( len("input pattern list") + 3 )
    hmsg += fmt % ("-p","input pattern list")

    fmt ="
%5s, %" +"%is" % ( len("output look up header file") + 3 )
    hmsg += fmt % ("-l","output look up header file")

    fmt ="
%5s, %" +"%is" % ( len("output pattern list header file") + 3 )
    hmsg += fmt % ("-f","output pattern list header file")

    fmt ="
%5s, %" +"%is" % ( len("print this message") + 3 )
    hmsg += fmt % ("-h","print this message")

    print hmsg

    exit(0)


def getPatternList(patStr):
    pl = (patStr.strip("{}")).split(',')
    return [ int(i) & 255  for i in pl ]


def parseOpt():
    patList = [ 255 ] # Default pattern
    luFile = sys.stdout
    patFile = sys.stdout

    try:
        opts, args = getopt.getopt(sys.argv[1:],"hp:l:f:", ["help","patterns="])
    except getopt.GetoptError:
        msg()

    for op in opts:
        if op[0] == '-p':
            patList = getPatternList(op[1])
        elif op[0] == '-l':
            luFile = open(op[1], 'w')
        elif op[0] == '-f':
            patFile = open(op[1], 'w')
        elif op[0] == '-h':
            msg()

    return (patList, luFile, patFile)    


def main():
    (patList, luFile, patFile)  = parseOpt()
    lug = LUPattern(patList)
    print >> luFile , lug.genCode()
    print >> patFile, lug.patCode()

    patFile.close()
    luFile.close()


if __name__ =="__main__":
    main()

< BR>

C代码

现在,在调用上述脚本之后,它将生成两个文件:lu.h和pl.h。关于我们新的C项目的文件。下面是一个简单的C代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include"pl.h"
#include"lu.h"
#include <stdio.h>


int main(void)
{
  uint32_t stats[SZ + 1] = { 0 };
  uint8_t b;

  while( fscanf(stdin,"%c", &b) != EOF )
  {
    (void)lu[b];
    // lu[b] has bytes that don't match with b
  }

  return 0;
}

< BR>

测试和基准:

我做了一些额外的工作来检查和获得结果。有我用作测试用例单元的更多代码,但我不粘贴在这里(如果你愿意,我以后再粘贴)。

我为同一个实用程序制作了两个相似的版本。一次性查找表(noloop版本)另一个使用典型的循环(循环版本)。< BR>循环代码与noloop代码稍有不同,但我尽量减少这些差异。

NOLOOP版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include"pl.h"
#include"lu.h"
#include <stdio.h>


void doStats(const uint8_t * const, uint32_t * const);
void printStats(const uint32_t * const);


int main(void)
{
  uint32_t stats[SZ + 1] = { 0 };
  uint8_t b;

  while( fscanf(stdin,"%c", &b) != EOF )
  {
    /* lu[b] has pattern values that not match with input b */
    doStats(lu[b], stats);
  }
  printStats(stats);

  return 0;
}


void doStats(const uint8_t * const noBitMatch, uint32_t * const stats)
{
  uint8_t i, j = 0;

  if(noBitMatch)
  {
    for(i = 0; noBitMatch[i] != 0; i++)
      for(; j < SZ; j++)
        if( noBitMatch[i] == patList[j] )
        {
          stats[j]++;
          break;
        }
  }
  else
    stats[SZ]++;

}


void printStats(const uint32_t * const stats)
{
  const uint8_t * const patList = lu[0];
  uint8_t i;

  printf("Stats:
");
  for(i = 0; i < SZ; i++)
    printf("  %3i%-3c%9i
", patList[i], ':', stats[i]);
  printf("  ---%-3c%9i
", ':', stats[SZ]);
}

< BR>循环版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include"pl.h"
#include <stdio.h>
#include <stdint.h>
#include <string.h>


void getNoBitMatch(const uint8_t, uint8_t * const);
void doStats(const uint8_t * const, uint32_t * const);
void printStats(const uint32_t * const);


int main(void)
{
  uint8_t b;
  uint8_t noBitMatch[SZ];
  uint32_t stats[SZ + 1] = { 0 };

  while( fscanf(stdin,"%c", &b ) != EOF )
  {    
    getNoBitMatch(b, noBitMatch);
    doStats(noBitMatch, stats);
  }
  printStats(stats);

  return 0;
}


void doStats(const uint8_t * const noBitMatch, uint32_t * const stats)
{
  uint32_t i;
  uint8_t f;

  for(i = 0, f = 0; i < SZ; i++)
  {
    f = ( (noBitMatch[i]) ? 1 : f );    
    stats[i] += noBitMatch[i];
  }

  stats[SZ] += (f) ? 0 : 1;
}


void getNoBitMatch(const uint8_t b, uint8_t * const noBitMatch)
{
  uint8_t i;

  for(i = 0; i < SZ; i++)
    noBitMatch[i] = ( (b & patList[i]) == 0 ) ? 1 : 0;
}


void printStats(const uint32_t * const stats)
{
  uint8_t i;

  printf("Stats:
");
  for(i = 0; i < SZ; i++)
    printf("  %3i%-3c%9i
", patList[i], ':', stats[i]);
  printf("  ---%-3c%9i
", ':', stats[SZ]);
}

这两个代码执行相同的操作:计算与模式列表(pl.h)的具体字节不匹配的字节数。

生成用于编译它们的文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
###

CC = gcc
CFLAGS = -c -Wall
SPDUP = -O3
DEBUG = -ggdb3 -O0
EXECUTABLE = noloop
AUXEXEC = loop

LU_SCRIPT = ./lup.py
LU_HEADER = lu.h
LU_PATLIST_HEADER = pl.h

#LU_PATLIST = -p"{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }"
#LU_PATLIST = -p"{ 3, 6, 12, 15, 32, 48, 69, 254 }"
LU_PATLIST = -p"{ 3, 6, 12, 48 }"
#LU_PATLIST = -p"{ 1, 2 }"
#LU_PATLIST = -p"{ 1 }"
LU_FILE = -l $(LU_HEADER)
LU_PAT_FILE = -f $(LU_PATLIST_HEADER)


SRC= noloop.c loop.c

SOURCE = $(EXECUTABLE).c
OBJECTS = $(SOURCE:.c=.o)

AUXSRC = $(AUXEXEC).c
AUXOBJ = $(AUXSRC:.c=.o)


all: $(EXECUTABLE) $(AUXEXEC)

lookup:
    $(LU_SCRIPT) $(LU_PATLIST) $(LU_FILE) $(LU_PAT_FILE)
    touch $(SRC)

$(EXECUTABLE): lookup $(OBJECTS)
    $(CC) $(OBJECTS) -o $@

$(AUXEXEC): $(AUXOBJ)
    $(CC) $(AUXOBJ) -o $@

.c.o:
    $(CC) $(CFLAGS) $(SPDUP) -c $<

debug: lookup dbg
    $(CC) $(OBJECTS) -o $(EXECUTABLE)
    $(CC) $(AUXOBJ) -o $(AUXEXEC)

dbg: *.c
    $(CC) $(CFLAGS) $(DEBUG) -c $<

clean:
    rm -f $(EXECUTABLE) $(AUXEXEC) *.o &> /dev/null

.PHONY: clean

我使用了三个纯文本作为输入流:GPLv3纯文本、神圣圣经纯文本和使用递归cat工具的Linux内核源代码。< BR>使用不同的模式列表执行此代码会得到以下结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
Sat Sep 24 15:03:18 CEST 2011


 Test1:  test/gpl.txt (size: 35147)
---------------------------------------------------

 Look up table version:
------------------------
Stats:
    1:      18917
    2:      22014
    3:      12423
    4:      19015
    5:      11111
    6:      12647
    7:       7791
    8:      23498
    9:      13637
   10:      16032
   11:       9997
   12:      14059
   13:       9225
   14:       8609
   15:       6629
   16:      25610
  ---:          0

real    0m0.016s
user    0m0.008s
sys     0m0.016s

 Loop version:
------------------------
Stats:
    1:      18917
    2:      22014
    3:      12423
    4:      19015
    5:      11111
    6:      12647
    7:       7791
    8:      23498
    9:      13637
   10:      16032
   11:       9997
   12:      14059
   13:       9225
   14:       8609
   15:       6629
   16:      25610
  ---:          0

real    0m0.020s
user    0m0.020s
sys     0m0.008s


 Test2:  test/HolyBible.txt (size: 5918239)
---------------------------------------------------

 Look up table version:
------------------------
Stats:
    1:    3392095
    2:    3970343
    3:    2325421
    4:    3102869
    5:    1973137
    6:    2177366
    7:    1434363
    8:    3749010
    9:    2179167
   10:    2751134
   11:    1709076
   12:    2137823
   13:    1386038
   14:    1466132
   15:    1072405
   16:    4445367
  ---:       3310

real    0m1.048s
user    0m1.044s
sys     0m0.012s

 Loop version:
------------------------
Stats:
    1:    3392095
    2:    3970343
    3:    2325421
    4:    3102869
    5:    1973137
    6:    2177366
    7:    1434363
    8:    3749010
    9:    2179167
   10:    2751134
   11:    1709076
   12:    2137823
   13:    1386038
   14:    1466132
   15:    1072405
   16:    4445367
  ---:       3310

real    0m0.926s
user    0m0.924s
sys     0m0.016s


 Test3:  test/linux-kernel-3.0.4 (size: 434042620)
---------------------------------------------------

 Look up table version:
------------------------
Stats:
    1:  222678565
    2:  254789058
    3:  137364784
    4:  239010012
    5:  133131414
    6:  146334792
    7:   83232971
    8:  246531446
    9:  145867949
   10:  161728907
   11:  103142808
   12:  147836792
   13:   93927370
   14:   87122985
   15:   66624721
   16:  275921653
  ---:   16845505

real    2m22.900s
user    3m43.686s
sys     1m14.613s

 Loop version:
------------------------
Stats:
    1:  222678565
    2:  254789058
    3:  137364784
    4:  239010012
    5:  133131414
    6:  146334792
    7:   83232971
    8:  246531446
    9:  145867949
   10:  161728907
   11:  103142808
   12:  147836792
   13:   93927370
   14:   87122985
   15:   66624721
   16:  275921653
  ---:   16845505

real    2m42.560s
user    3m56.011s
sys     1m26.037s


 Test4:  test/gpl.txt (size: 35147)
---------------------------------------------------

 Look up table version:
------------------------
Stats:
    3:      12423
    6:      12647
   12:      14059
   15:       6629
   32:       2338
   48:       1730
   69:       6676
  254:          0
  ---:      11170

real    0m0.011s
user    0m0.004s
sys     0m0.016s

 Loop version:
------------------------
Stats:
    3:      12423
    6:      12647
   12:      14059
   15:       6629
   32:       2338
   48:       1730
   69:       6676
  254:          0
  ---:      11170

real    0m0.021s
user    0m0.020s
sys     0m0.008s


 Test5:  test/HolyBible.txt (size: 5918239)
---------------------------------------------------

 Look up table version:
------------------------
Stats:
    3:    2325421
    6:    2177366
   12:    2137823
   15:    1072405
   32:     425404
   48:     397564
   69:    1251668
  254:          0
  ---:    1781959

real    0m0.969s
user    0m0.936s
sys     0m0.048s

 Loop version:
------------------------
Stats:
    3:    2325421
    6:    2177366
   12:    2137823
   15:    1072405
   32:     425404
   48:     397564
   69:    1251668
  254:          0
  ---:    1781959

real    0m1.447s
user    0m1.424s
sys     0m0.032s


 Test6:  test/linux-kernel-3.0.4 (size: 434042620)
---------------------------------------------------

 Look up table version:
------------------------
Stats:
    3:  137364784
    6:  146334792
   12:  147836792
   15:   66624721
   32:   99994388
   48:   64451562
   69:   89249942
  254:       5712
  ---:  105210728

real    2m38.851s
user    3m37.510s
sys     1m26.653s

 Loop version:
------------------------
Stats:
    3:  137364784
    6:  146334792
   12:  147836792
   15:   66624721
   32:   99994388
   48:   64451562
   69:   89249942
  254:       5712
  ---:  105210728

real    2m32.041s
user    3m36.022s
sys     1m27.393s


 Test7:  test/gpl.txt (size: 35147)
---------------------------------------------------

 Look up table version:
------------------------
Stats:
    3:      12423
    6:      12647
   12:      14059
   48:       1730
  ---:      11277

real    0m0.013s
user    0m0.016s
sys     0m0.004s

 Loop version:
------------------------
Stats:
    3:      12423
    6:      12647
   12:      14059
   48:       1730
  ---:      11277

real    0m0.014s
user    0m0.020s
sys     0m0.000s


 Test8:  test/HolyBible.txt (size: 5918239)
---------------------------------------------------

 Look up table version:
------------------------
Stats:
    3:    2325421
    6:    2177366
   12:    2137823
   48:     397564
  ---:    1850018

real    0m0.933s
user    0m0.916s
sys     0m0.036s

 Loop version:
------------------------
Stats:
    3:    2325421
    6:    2177366
   12:    2137823
   48:     397564
  ---:    1850018

real    0m0.892s
user    0m0.860s
sys     0m0.052s


 Test9:  test/linux-kernel-3.0.4 (size: 434042620)
---------------------------------------------------

 Look up table version:
------------------------
Stats:
    3:  137364784
    6:  146334792
   12:  147836792
   48:   64451562
  ---:  132949214

real    2m31.187s
user    3m31.289s
sys     1m25.909s

 Loop version:
------------------------
Stats:
    3:  137364784
    6:  146334792
   12:  147836792
   48:   64451562
  ---:  132949214

real    2m34.942s
user    3m33.081s
sys     1m24.381s


 Test10:  test/gpl.txt (size: 35147)
---------------------------------------------------

 Look up table version:
------------------------
Stats:
    1:      18917
    2:      22014
  ---:       6639

real    0m0.014s
user    0m0.016s
sys     0m0.008s

 Loop version:
------------------------
Stats:
    1:      18917
    2:      22014
  ---:       6639

real    0m0.017s
user    0m0.016s
sys     0m0.008s


 Test11:  test/HolyBible.txt (size: 5918239)
---------------------------------------------------

 Look up table version:
------------------------
Stats:
    1:    3392095
    2:    3970343
  ---:     881222

real    0m0.861s
user    0m0.848s
sys     0m0.032s

 Loop version:
------------------------
Stats:
    1:    3392095
    2:    3970343
  ---:     881222

real    0m0.781s
user    0m0.760s
sys     0m0.044s


 Test12:  test/linux-kernel-3.0.4 (size: 434042620)
---------------------------------------------------

 Look up table version:
------------------------
Stats:
    1:  222678565
    2:  254789058
  ---:   84476465

real    2m29.894s
user    3m30.449s
sys     1m23.177s

 Loop version:
------------------------
Stats:
    1:  222678565
    2:  254789058
  ---:   84476465

real    2m21.103s
user    3m22.321s
sys     1m24.001s


 Test13:  test/gpl.txt (size: 35147)
---------------------------------------------------

 Look up table version:
------------------------
Stats:
    1:      18917
  ---:      16230

real    0m0.015s
user    0m0.020s
sys     0m0.008s

 Loop version:
------------------------
Stats:
    1:      18917
  ---:      16230

real    0m0.016s
user    0m0.016s
sys     0m0.008s


 Test14:  test/HolyBible.txt (size: 5918239)
---------------------------------------------------

 Look up table version:
------------------------
Stats:
    1:    3392095
  ---:    2526144

real    0m0.811s
user    0m0.808s
sys     0m0.024s

 Loop version:
------------------------
Stats:
    1:    3392095
  ---:    2526144

real    0m0.709s
user    0m0.688s
sys     0m0.040s


 Test15:  test/linux-kernel-3.0.4 (size: 434042620)
---------------------------------------------------

 Look up table version:
------------------------
Stats:
    1:  222678565
  ---:  201900739

real    2m21.510s
user    3m23.009s
sys     1m23.861s

 Loop version:
------------------------
Stats:
    1:  222678565
  ---:  201900739

real    2m22.677s
user    3m26.477s
sys     1m23.385s


Sat Sep 24 15:28:28 CEST 2011

< BR>

结论:

在我看来,使用查找表可以通过增加代码大小,但改进并不太多意义重大。要开始注意差异,输入字节的数量应该巨大。


我唯一能想到的就是减少测试次数:

1
2
3
4
5
6
7
8
9
10
11
for(int p1=1; p1<pool.Length; p1++)
{
  for(int p2=0; p2<p1; p1++)
  {
    if((pool[p1] & pool[p2])==0)
    {
      //byte at p1 works with byte at p2.
      //byte at p2 works with byte at p1.
    }
  }
}