Skip to content

Instantly share code, notes, and snippets.

@omochi
Created February 5, 2020 06:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save omochi/29f5aae812d4556c96ab289ee48fa937 to your computer and use it in GitHub Desktop.
Save omochi/29f5aae812d4556c96ab289ee48fa937 to your computer and use it in GitHub Desktop.

knots-memo-2と同様の発想で、 今度は、Reduceの中の検索部分の実行回数を調べてみた。

ReduceはC++でもSwiftでも、3重ループになっていて、 その内側に検索がある。

C++の場合は連結リストからのリニアスキャンで、O(N)で遅く見える。 Swiftの場合はSetへの存在チェックで、O(1)で速く見える。

C++の計測コード

                // For every source->k
                for(list<int>::iterator k = Graph[MM][source].out.begin();
                    k != Graph[MM][source].out.end(); k++) {
                    
                    searchCount += 1;
                    int searchRangeSize = (int)Graph[MM][*j].out.size();
                    
                    maxSearchRangeSize = max(maxSearchRangeSize, searchRangeSize);
                    
                    searchRangeSizeSum += searchRangeSize;
                    
                    // Search for j->k. If found, remove it; if not, add it.
                    list<int>::iterator search;
                    for(search = Graph[MM][*j].out.begin();
                        search != Graph[MM][*j].out.end(); search++ )
                    {

出力コード

    printf("@@@ Reduce(MM=%2d): searchCount=%8d, size=%8d, ave=%6d, max=%6d, allSearchCount=%8d\n",
           MM, searchCount, searchRangeSizeSum,
           searchCount > 0 ? (int)((float)searchRangeSizeSum / (float)searchCount) : 0,
           maxSearchRangeSize,
           allSearchCount);

MMのステップに対する 検索が行われた回数と、 検索対象のサイズ x 検索回数、 検索一回あたりの平均対象サイズ、 最大の検索対象サイズ、 プログラム全体での検索回数 を出している。

同じことをSwiftでは下記で計測

                
                for a in graph.cotargets[y] ?? [] where a != x {
                    for b in graph.targets[x] ?? [] where b != y {
                        
                        searchCount += 1
                        searchRangeSize = graph.targets[a]?.count ?? 0
                        searchRangeSizeSum += searchRangeSize
                        maxSearchRangeSize = max(maxSearchRangeSize, searchRangeSize)
                        
                        if graph.targets[a]?.contains(b) ?? false {
                            graph.disconnect(a, b)
                        } else {
                            graph.connect(a, b)
                        }
                    }
                }

で、結果。

C++

@@@ Reduce(MM=39): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=       0
@@@ Reduce(MM=38): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=       0
@@@ Reduce(MM=37): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=       0
@@@ Reduce(MM=36): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=       0
@@@ Reduce(MM=35): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=       0
@@@ Reduce(MM=34): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=       0
@@@ Reduce(MM=33): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=       0
@@@ Reduce(MM=32): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=       0
@@@ Reduce(MM=31): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=       0
@@@ Reduce(MM=30): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=       0
@@@ Reduce(MM=29): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=       0
@@@ Reduce(MM=28): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=       0
@@@ Reduce(MM=27): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=       0
@@@ Reduce(MM=26): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=       0
@@@ Reduce(MM=25): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=       0
@@@ Reduce(MM=24): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=       0
@@@ Reduce(MM=23): searchCount=      81, size=     909, ave=    11, max=    22, allSearchCount=      81
@@@ Reduce(MM=22): searchCount=    1699, size=   19999, ave=    11, max=    37, allSearchCount=    1780
@@@ Reduce(MM=21): searchCount=   12383, size=  164141, ave=    13, max=    78, allSearchCount=   14163
@@@ Reduce(MM=20): searchCount=   28470, size=  334130, ave=    11, max=    60, allSearchCount=   42633
@@@ Reduce(MM=19): searchCount=    9395, size=   68891, ave=     7, max=    27, allSearchCount=   52028
@@@ Reduce(MM=18): searchCount=    2518, size=   13643, ave=     5, max=    17, allSearchCount=   54546
@@@ Reduce(MM=17): searchCount=     363, size=    1316, ave=     3, max=     7, allSearchCount=   54909
@@@ Reduce(MM=16): searchCount=      28, size=      71, ave=     2, max=     4, allSearchCount=   54937
@@@ Reduce(MM=15): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=   54937
@@@ Reduce(MM=14): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=   54937
@@@ Reduce(MM=13): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=   54937
@@@ Reduce(MM=12): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=   54937
@@@ Reduce(MM=11): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=   54937
@@@ Reduce(MM=10): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=   54937
@@@ Reduce(MM= 9): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=   54937
@@@ Reduce(MM= 8): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=   54937
@@@ Reduce(MM= 7): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=   54937
@@@ Reduce(MM= 6): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=   54937
@@@ Reduce(MM= 5): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=   54937
@@@ Reduce(MM= 4): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=   54937
@@@ Reduce(MM= 3): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=   54937
@@@ Reduce(MM= 2): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=   54937
@@@ Reduce(MM= 1): searchCount=       0, size=       0, ave=     0, max=     0, allSearchCount=   54937

Swift

@@@ loop= 0, alex= 0, k= 5: searchCount=       0, size=         0, ave=     0, max=     0 allSearchCount=       0
@@@ loop= 1, alex= 0, k= 4: searchCount=      48, size=       925, ave=    19, max=    26 allSearchCount=      48
@@@ loop= 2, alex= 0, k= 3: searchCount=    2069, size=     70958, ave=    34, max=    75 allSearchCount=    2117
@@@ loop= 3, alex= 0, k= 2: searchCount=   31431, size=   2126998, ave=    67, max=   187 allSearchCount=   33548
@@@ loop= 4, alex= 0, k= 1: searchCount=  396656, size=  46550351, ave=   117, max=   285 allSearchCount=  430204
@@@ loop= 5, alex= 0, k= 0: searchCount= 1313313, size= 185287215, ave=   141, max=   335 allSearchCount= 1743517
@@@ loop= 6, alex= 0, k=-1: searchCount= 1186708, size= 132173551, ave=   111, max=   219 allSearchCount= 2930225
@@@ loop= 7, alex= 0, k=-2: searchCount=  123215, size=   4429047, ave=    35, max=   104 allSearchCount= 3053440
@@@ loop= 8, alex= 0, k=-3: searchCount=    6571, size=     68080, ave=    10, max=    28 allSearchCount= 3060011
@@@ loop= 9, alex= 0, k=-4: searchCount=     355, size=      1546, ave=     4, max=     9 allSearchCount= 3060366
@@@ loop=10, alex= 0, k=-5: searchCount=      12, size=        24, ave=     2, max=     2 allSearchCount= 3060378
@@@ loop=11, alex= 0, k=-6: searchCount=       0, size=         0, ave=     0, max=     0 allSearchCount= 3060378
@@@ loop=12, alex= 0, k=-7: searchCount=       0, size=         0, ave=     0, max=     0 allSearchCount= 3060378
@@@ loop=13, alex= 1, k= 4: searchCount=       0, size=         0, ave=     0, max=     0 allSearchCount= 3060378
@@@ loop=14, alex= 1, k= 3: searchCount=     168, size=      1871, ave=    11, max=    21 allSearchCount= 3060546
@@@ loop=15, alex= 1, k= 2: searchCount=    2889, size=     49520, ave=    17, max=    47 allSearchCount= 3063435
@@@ loop=16, alex= 1, k= 1: searchCount=   13242, size=    293523, ave=    22, max=    76 allSearchCount= 3076677
@@@ loop=17, alex= 1, k= 0: searchCount=    8554, size=    188709, ave=    22, max=    63 allSearchCount= 3085231
@@@ loop=18, alex= 1, k=-1: searchCount=    3259, size=     39896, ave=    12, max=    30 allSearchCount= 3088490
@@@ loop=19, alex= 1, k=-2: searchCount=     403, size=      2234, ave=     5, max=    12 allSearchCount= 3088893
@@@ loop=20, alex= 1, k=-3: searchCount=      12, size=        24, ave=     2, max=     2 allSearchCount= 3088905
@@@ loop=21, alex= 1, k=-4: searchCount=       0, size=         0, ave=     0, max=     0 allSearchCount= 3088905
@@@ loop=22, alex= 1, k=-5: searchCount=       0, size=         0, ave=     0, max=     0 allSearchCount= 3088905
@@@ loop=23, alex= 2, k= 4: searchCount=       0, size=         0, ave=     0, max=     0 allSearchCount= 3088905
@@@ loop=24, alex= 2, k= 3: searchCount=      27, size=       185, ave=     6, max=     9 allSearchCount= 3088932
@@@ loop=25, alex= 2, k= 2: searchCount=     164, size=      1048, ave=     6, max=    16 allSearchCount= 3089096
@@@ loop=26, alex= 2, k= 1: searchCount=      68, size=       307, ave=     4, max=     8 allSearchCount= 3089164
@@@ loop=27, alex= 2, k= 0: searchCount=      29, size=       107, ave=     3, max=     6 allSearchCount= 3089193
@@@ loop=28, alex= 2, k=-1: searchCount=       4, size=         8, ave=     2, max=     2 allSearchCount= 3089197
@@@ loop=29, alex= 2, k=-2: searchCount=       0, size=         0, ave=     0, max=     0 allSearchCount= 3089197
@@@ loop=30, alex= 2, k=-3: searchCount=       0, size=         0, ave=     0, max=     0 allSearchCount= 3089197
@@@ loop=31, alex= 3, k= 4: searchCount=       0, size=         0, ave=     0, max=     0 allSearchCount= 3089197
@@@ loop=32, alex= 3, k= 3: searchCount=       2, size=         7, ave=     3, max=     4 allSearchCount= 3089199
@@@ loop=33, alex= 3, k= 2: searchCount=       1, size=         2, ave=     2, max=     2 allSearchCount= 3089200
@@@ loop=34, alex= 3, k= 1: searchCount=       0, size=         0, ave=     0, max=     0 allSearchCount= 3089200
@@@ loop=35, alex= 3, k= 0: searchCount=       0, size=         0, ave=     0, max=     0 allSearchCount= 3089200

プログラム全体での合計検索回数が、 5万と300万で、60倍の差がついている。

平均探索サイズもだいぶ違う。 C++の方はだいたい10個ぐらい。 Swiftの方は100ぐらい。

10個ぐらいの連結リストのリニアスキャンと、 100個ぐらいのSetのハッシュ検索だと、 検索時間としてはほぼ同じぐらいになる気がする。

どちらもmaxの値を見た感じ、 極端に歪んだ分布になっていることは無さそう。 C++のMM=20のケースについては、 生の値をダンプしてみたけど、10〜20の範囲で適度にばらつく感じだった。

@omochi
Copy link
Author

omochi commented Feb 5, 2020

恐らく BuildEdges に
if(!Graph[MM][index]) continue;
を挿入すると、辺の生成総数は一致すると思います(そして計算もより速く…)

検証結果

@@@ BuildEdges(MM=39): edge=       0, allEdge=       0
@@@ BuildEdges(MM=38): edge=       0, allEdge=       0
@@@ BuildEdges(MM=37): edge=       0, allEdge=       0
@@@ BuildEdges(MM=36): edge=       0, allEdge=       0
@@@ BuildEdges(MM=35): edge=       0, allEdge=       0
@@@ BuildEdges(MM=34): edge=       0, allEdge=       0
@@@ BuildEdges(MM=33): edge=       0, allEdge=       0
@@@ BuildEdges(MM=32): edge=       0, allEdge=       0
@@@ BuildEdges(MM=31): edge=       0, allEdge=       0
@@@ BuildEdges(MM=30): edge=       0, allEdge=       0
@@@ BuildEdges(MM=29): edge=       0, allEdge=       0
@@@ BuildEdges(MM=28): edge=       0, allEdge=       0
@@@ BuildEdges(MM=27): edge=       0, allEdge=       0
@@@ BuildEdges(MM=26): edge=       0, allEdge=       0
@@@ BuildEdges(MM=25): edge=       9, allEdge=       9
@@@ BuildEdges(MM=24): edge=     175, allEdge=     184
@@@ BuildEdges(MM=23): edge=    1434, allEdge=    1618
@@@ BuildEdges(MM=22): edge=    6676, allEdge=    8294
@@@ BuildEdges(MM=21): edge=   17608, allEdge=   25902
@@@ BuildEdges(MM=20): edge=   23808, allEdge=   49710
@@@ BuildEdges(MM=19): edge=   15325, allEdge=   65035
@@@ BuildEdges(MM=18): edge=    6501, allEdge=   71536
@@@ BuildEdges(MM=17): edge=    1807, allEdge=   73343
@@@ BuildEdges(MM=16): edge=     330, allEdge=   73673
@@@ BuildEdges(MM=15): edge=      38, allEdge=   73711
@@@ BuildEdges(MM=14): edge=       2, allEdge=   73713
@@@ BuildEdges(MM=13): edge=       0, allEdge=   73713
@@@ BuildEdges(MM=12): edge=       0, allEdge=   73713
@@@ BuildEdges(MM=11): edge=       0, allEdge=   73713
@@@ BuildEdges(MM=10): edge=       0, allEdge=   73713
@@@ BuildEdges(MM= 9): edge=       0, allEdge=   73713
@@@ BuildEdges(MM= 8): edge=       0, allEdge=   73713
@@@ BuildEdges(MM= 7): edge=       0, allEdge=   73713
@@@ BuildEdges(MM= 6): edge=       0, allEdge=   73713
@@@ BuildEdges(MM= 5): edge=       0, allEdge=   73713
@@@ BuildEdges(MM= 4): edge=       0, allEdge=   73713
@@@ BuildEdges(MM= 3): edge=       0, allEdge=   73713
@@@ BuildEdges(MM= 2): edge=       0, allEdge=   73713
@@@ BuildEdges(MM= 1): edge=       0, allEdge=   73713

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment