├── .gitignore ├── BenchmarkData ├── benchmark-data.json └── chart.png ├── Package.resolved ├── Package.swift ├── README.md ├── Sources ├── BenchmarkCLI │ └── Main.swift └── Computation │ └── Fibonacci.swift └── Tests └── ComputationTests └── ConcurrencyBenchmarkTests.swift /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | /*.xcodeproj 5 | xcuserdata/ 6 | DerivedData/ 7 | .swiftpm/config/registries.json 8 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata 9 | .netrc 10 | -------------------------------------------------------------------------------- /BenchmarkData/benchmark-data.json: -------------------------------------------------------------------------------- 1 | {"version":1,"tasks":[{"title":"No parallelism (1 core)","results":{"57344":[0.0035761454999999999,0.0035768750000000002,0.0035824164999999999],"1280":[0.0031091669999999999,0.0031145000000000001,0.003117833],"48":[0.0031050840000000001,0.0031052916666666664,0.0031193750000000002],"56":[0.0030985000000000001,0.0031063750000000002,0.0031082499999999999],"98304":[0.0036598749999999999,0.0036768125,0.0037220625000000001],"64":[0.0031045420000000001,0.0031119860000000002,0.0031155409999999999],"131072":[0.0033759584999999998,0.0033776460000000002,0.0033778329999999998],"20480":[0.0032750420000000001,0.003277833,0.0033010000000000001],"80":[0.0031007359999999998,0.0031055416666666666,0.0031277499999999999],"1":[0.0031481249999999999,0.003162291666666667,0.0032053329999999999],"2":[0.0031134723333333335,0.0031965420000000001,0.003214167],"768":[0.003104833,0.0031073329999999999,0.0031229166666666666],"3":[0.0031040830000000001,0.0031072500000000002,0.003165125],"4":[0.0031008056666666666,0.003103958,0.003127417],"320":[0.003109667,0.0031117079999999999,0.0031821250000000001],"5":[0.003103541,0.003144333,0.0031954723333333331],"6":[0.0031038329999999999,0.0031065839999999999,0.0031960416666666665],"10240":[0.0031927079999999998,0.0031956250000000001,0.0032081660000000001],"7":[0.0031006666666666665,0.0031007920000000189,0.0031151249999999998],"24576":[0.0033219579999999999,0.0033352080000000001,0.0034070419999999999],"10":[0.0031008339999999998,0.0031075410000000001,0.0031163340000000001],"8":[0.0031007500000000002,0.003109583,0.003112666],"896":[0.0031097080000000001,0.0031112083333333334,0.0031120829999999999],"163840":[0.003454875,0.0034577290000000001,0.0035308334999999999],"3584":[0.0031310140000000001,0.0031327363333333333,0.0031416669999999999],"40960":[0.0034516249999999998,0.0034543339999999999,0.003457416],"1536":[0.0031115000000000001,0.0031259170000000002,0.0031259999999999999],"12":[0.0030998610000000002,0.0031041250000000001,0.003139167],"2560":[0.003129209,0.0031302640000000002,0.0033022920000000001],"65536":[0.0036402079999999998,0.0036453330000000002,0.003648625],"229376":[0.0035948335000000001,0.0035968545000000002,0.0036010625000000001],"512":[0.0031116249999999998,0.0031142499999999998,0.0031163330000000002],"20":[0.0030985000000000001,0.0031010830000000001,0.003109583],"81920":[0.0037336875,0.0037339790000000001,0.0037713335000000001],"14336":[0.0032299999999999998,0.003238875,0.0032616250000000002],"14":[0.0031072080000000002,0.0031190839999999998,0.003124417],"96":[0.0031047499999999999,0.003134375,0.0031810419999999998],"12288":[0.0032041249999999999,0.0032070829999999999,0.0032315276666666664],"128":[0.0031076526666666666,0.0031197640000000001,0.0031235830000000001],"49152":[0.0035400000000000002,0.003542042,0.0035586250000000002],"16":[0.0031022500000000004,0.0031039169999999999,0.003118666],"640":[0.0031254170000000001,0.0031301670000000001,0.0031771249999999998],"192":[0.0031061249999999999,0.0031087916666666664,0.003110514],"24":[0.0031061806666666668,0.003110958,0.003116583],"4096":[0.003135166,0.0031372079999999998,0.003142583],"32":[0.00312225,0.0031322089999999999,0.0031913056666666665],"2048":[0.0031197916666666665,0.0031217079999999999,0.003192486],"256":[0.0031097080000000001,0.0031202090000000001,0.0031319590000000001],"3072":[0.0031329579999999999,0.0031510409999999998,0.0032764999999999999],"1792":[0.0031234589999999999,0.0031256669999999999,0.0032841250000000002],"40":[0.0031012499999999998,0.0031075,0.0031292500000000001],"28672":[0.0033502919999999999,0.0033610624999999999,0.0033656670000000001],"1024":[0.0031125829999999999,0.0031189170000000001,0.0031197920000000001],"262144":[0.0036916875000000001,0.0036952500000000002,0.0037452079999999999],"7168":[0.0031644160000000002,0.0031715279999999998,0.0032595973333333331],"8192":[0.00317425,0.0031756670000000001,0.003180792],"28":[0.0030986659999999999,0.0031285136666666671,0.003206792],"32768":[0.0033897914999999998,0.0033940624999999999,0.0033955000000000001],"6144":[0.0031541659999999999,0.003160833,0.003165125],"384":[0.0031043329999999999,0.0031062080000000001,0.0031100839999999999],"160":[0.0031023330000000001,0.0031135830000000001,0.0031322089999999999],"5120":[0.0031607919999999999,0.0031753056666666665,0.0032520000000000001],"448":[0.0031081250000000002,0.003111333,0.0031181666666666667],"114688":[0.0033422289999999999,0.0033439164999999999,0.0034195835000000001],"16384":[0.0032473329999999998,0.0032503749999999998,0.0032530419999999998],"112":[0.0031012639999999998,0.0031076250000000001,0.003114375],"224":[0.0031059170000000001,0.003108708,0.0031110420000000001],"196608":[0.0035173545000000001,0.0035218749999999998,0.0035271874999999999]}},{"title":"concurrentPerform","results":{"57344":[0.0042096249999999998,0.0043302499999999999,0.0043414999999999999],"1280":[0.00048608400000000002,0.00051005788888888889,0.00051345799999999995],"48":[0.00045620799999999999,0.00047241600000000003,0.0004834021],"56":[0.00044212500000000003,0.00044780566666666665,0.00045395366666666669],"98304":[0.0062446250000000002,0.0068161669999999997,0.0071452080000000001],"64":[0.00042041700000000002,0.00046387499999999999,0.00046737500000000002],"131072":[0.0094143330000000004,0.010008625,0.010489812499999999],"20480":[0.001732042,0.0017521749999999999,0.0017931665999999999],"80":[0.00048525,0.00048711045000000001,0.00048829199999999998],"1":[0.0031629306666666663,0.0031646666666666668,0.0032319583333333332],"2":[0.0016284590000000001,0.0016335973333333335,0.0016624579999999999],"768":[0.00047420900000000001,0.00047991599999999999,0.00050458399999999998],"3":[0.00113203125,0.0011389635,0.001144984375],"4":[0.00085934463636363643,0.00086818563636363632,0.00092261250000000002],"320":[0.00041889549999999997,0.00042166700000000003,0.00043691666666666667],"5":[0.00067687499999999996,0.00068441699999999999,0.00075179200000000004],"6":[0.00060154200000000005,0.000605209,0.00062887220000000001],"10240":[0.000887917,0.00090133300000000004,0.00090187500000000001],"7":[0.000524417,0.00052637988235294114,0.00052692361111111115],"24576":[0.0020037089999999998,0.0020403750000000001,0.0021072909999999999],"10":[0.00054066699999999999,0.00066766700000000004,0.00066837200000000008],"8":[0.00046375000000000002,0.00047162499999999998,0.00048885425000000002],"896":[0.00046383399999999999,0.00047508400000000002,0.00055062500000000001],"163840":[0.010987812499999999,0.01100725,0.012068000000000001],"3584":[0.00053287500000000004,0.00055175000000000005,0.00060524999999999999],"40960":[0.002926416666666667,0.0031137920000000002,0.0031826670000000001],"1536":[0.00048000000000000001,0.00051516699999999997,0.00051720800000000001],"12":[0.00057828676470588229,0.00059009112499999999,0.00060298700000000003],"2560":[0.00048983299999999996,0.00052170799999999996,0.00063624999999999999],"65536":[0.0049722500000000001,0.0051287080000000001,0.0052069170000000001],"229376":[0.015434,0.016318124999999999,0.017070292000000001],"512":[0.00048268749999999999,0.00052508399999999999,0.00052762499999999999],"20":[0.00051808300000000002,0.00052705094444444435,0.0005345787222222222],"81920":[0.0048890000000000001,0.0061155419999999999,0.0062260420000000002],"14336":[0.00095037500000000005,0.00095112500000000004,0.00114175525],"14":[0.00051824264705882354,0.00052039217647058831,0.00055966423529411771],"96":[0.00042537500000000003,0.00042575000000000002,0.00044255839999999999],"12288":[0.00088004200000000004,0.001010625,0.0010375],"128":[0.00041822199999999999,0.00046733300000000001,0.00053085183333333326],"49152":[0.0028781875000000001,0.0032348749999999999,0.0034909580000000002],"16":[0.00050516700000000005,0.00051741700000000005,0.00061968333333333326],"640":[0.00046250000000000002,0.00047074999999999998,0.00051241600000000002],"192":[0.0004488955,0.00050000436842105264,0.00052279099999999999],"24":[0.00046191599999999999,0.00052692968749999995,0.00056183399999999999],"4096":[0.00052708300000000002,0.00056333299999999995,0.00061074999999999996],"32":[0.000465167,0.00046559375000000002,0.00046698962500000001],"2048":[0.00045774999999999999,0.00056195799999999999,0.00061658299999999997],"256":[0.00044816700000000002,0.000475334,0.00049283300000000003],"3072":[0.00053133300000000004,0.00058850524999999999,0.00063863692857142856],"1792":[0.00046533399999999997,0.00051204099999999997,0.00052370800000000001],"40":[0.00046281250000000001,0.00052133856250000002,0.00053103238888888894],"28672":[0.00225665625,0.0022654160000000001,0.0023158332500000001],"1024":[0.00046174999999999998,0.00052154199999999995,0.00055762499999999996],"262144":[0.017423999999999999,0.018760625,0.019922209],"7168":[0.00063754100000000004,0.00068687499999999999,0.00074724999999999998],"8192":[0.00075925000000000005,0.00076358299999999997,0.00076429199999999997],"28":[0.00047033399999999999,0.00050813157894736844,0.00054771300000000002],"32768":[0.0025254583333333331,0.0025939169999999998,0.0026497080000000002],"6144":[0.00060120799999999999,0.00065074999999999996,0.00068325000000000005],"384":[0.000452958,0.00046895900000000002,0.00051771926315789482],"160":[0.00042909733333333335,0.000468417,0.00047870900000000001],"5120":[0.00060516599999999997,0.00060924999999999998,0.00066254200000000001],"448":[0.00044424999999999998,0.00047291599999999998,0.00054362499999999995],"114688":[0.0064020409999999998,0.0083260000000000001,0.0084545000000000002],"16384":[0.0014473193333333332,0.001448291,0.0014699028333333333],"112":[0.00045862499999999999,0.00046733300000000001,0.000551375],"224":[0.0004355276666666667,0.00044362500000000001,0.00044983300000000001],"196608":[0.0131261665,0.013474415999999999,0.014278499999999972]}},{"title":"DispatchQueue.global().async","results":{"57344":[0.025364978999999999,0.026043416999999999,0.028207166999999998],"1280":[0.001316458,0.0017505000000000001,0.0021563749999999999],"48":[0.000499834,0.0005161458333333333,0.00052583566666666664],"56":[0.00047795800000000001,0.00048604099999999999,0.000490125],"98304":[0.037400707999999998,0.041276374999999997,0.043605375000000002],"64":[0.00049958399999999997,0.0005375,0.00055674264705882356],"131072":[0.052513625000000001,0.053882791499999999,0.0600418125],"20480":[0.010843042000000001,0.011447832999999999,0.012588895500000001],"80":[0.00048500000000000003,0.00055729200000000003,0.00056700000000000001],"1":[0.0031279580000000001,0.0031433749999999999,0.0031847219999999996],"2":[0.001632611,0.0016333750000000001,0.0016605666000000002],"768":[0.00085183299999999997,0.001243875,0.001436042],"3":[0.0011545419999999999,0.0011598750000000001,0.0011607447500000001],"4":[0.00087058399999999998,0.00087124999999999995,0.00087187500000000004],"320":[0.00054795799999999997,0.00061791700000000005,0.00078604200000000003],"5":[0.00072420799999999995,0.00075360758333333335,0.00075845192307692311],"6":[0.00062720799999999998,0.00063638613333333338,0.00063645800000000001],"10240":[0.0060667079999999996,0.0067482499999999999,0.0074212499999999999],"7":[0.00058912500000000002,0.00059729200000000003,0.00060056386666666674],"24576":[0.012631041500000001,0.013089708,0.0132337915],"10":[0.00061437500000000001,0.00066111007142857152,0.00066208399999999996],"8":[0.00054564318749999996,0.00054979200000000001,0.00055128676470588239],"896":[0.00094995799999999999,0.0011594159999999999,0.0015811250000000001],"163840":[0.065817125000000004,0.067712790999999994,0.070286000000000015],"3584":[0.0026597080000000002,0.0029434579999999999,0.0029504026666666663],"40960":[0.017642374999999998,0.0198365,0.021059083499999999],"1536":[0.0015556669999999999,0.001634833,0.0016602500000000001],"12":[0.00059509637499999995,0.00060470900000000004,0.00060520799999999998],"2560":[0.0020254169999999998,0.002130042,0.0024762920000000002],"65536":[0.030101625,0.030553041999999999,0.031740375000000001],"229376":[0.093628332999999994,0.096845916500000004,0.097004979000000005],"512":[0.00067587500000000004,0.00078329099999999998,0.00086625000000000005],"20":[0.00055943750000000004,0.00056004164705882346,0.00059277862499999996],"81920":[0.036836208000000002,0.037534479000000003,0.038138125000000002],"14336":[0.0074183340000000004,0.0075045839999999999,0.0076713329999999998],"14":[0.00055091700000000005,0.00056334799999999997,0.00057783400000000005],"96":[0.00049466600000000005,0.00051912499999999995,0.00055012500000000005],"12288":[0.0067320419999999997,0.0070067080000000004,0.0091739999999999999],"128":[0.00051650000000000003,0.000531,0.00059237500000000002],"49152":[0.023163458000000001,0.023986500000000001,0.024219625000000002],"16":[0.00054045799999999995,0.00054925000000000004,0.00057601485714285714],"640":[0.00094829099999999998,0.00099379200000000007,0.001250333],"192":[0.00053237499999999997,0.00057295899999999995,0.000575875],"24":[0.00051515738888888889,0.00054343977777777778,0.00055487500000000003],"4096":[0.0027941670000000002,0.003046708,0.0030555833333333333],"32":[0.00051308300000000001,0.00052160450000000001,0.00052249766666666666],"2048":[0.001539208,0.0019087500000000001,0.0019857080000000001],"256":[0.00051679199999999997,0.00066374999999999995,0.00073562499999999995],"3072":[0.0020175000000000002,0.00218775,0.0024747910000000001],"1792":[0.001566792,0.001758208,0.002042875],"40":[0.00047054200000000001,0.00051385188888888888,0.00051612499999999998],"28672":[0.014494833,0.014857291999999999,0.015368],"1024":[0.0013241308571428571,0.001337083,0.0015110903333333335],"262144":[0.1073242915,0.110068833,0.110196208],"7168":[0.0039840409999999998,0.0044627080000000001,0.004746208],"8192":[0.0044296250000000004,0.0044302919999999997,0.0053254160000000004],"28":[0.00051941666666666672,0.00052558300000000004,0.00053450233333333333],"32768":[0.016681499999999998,0.016749666999999999,0.017792833000000001],"6144":[0.0038099169999999999,0.0041679165000000004,0.0044939580000000002],"384":[0.00060462500000000002,0.00086445800000000002,0.000865875],"160":[0.00049620899999999995,0.00049683400000000003,0.00052883400000000005],"5120":[0.0032098750000000001,0.0033195,0.0036267080000000002],"448":[0.00064050000000000001,0.00078587500000000001,0.00086129100000000003],"114688":[0.048268040999999998,0.050258667,0.054343542000000002],"16384":[0.0083813954999999996,0.0091730000000000006,0.0093259789999999999],"112":[0.00051124999999999999,0.000536708,0.00058200000000000005],"224":[0.00055658400000000005,0.00057833299999999999,0.00057916599999999999],"196608":[0.078217937500000001,0.078297000000000005,0.080685791500000006]}},{"title":"TaskGroup","results":{"57344":[0.060365624999999999,0.060760665999999998,0.062582853999999993],"1280":[0.001712959,0.001879583,0.001923875],"48":[0.00048916699999999999,0.00051856711111111114,0.00053081483333333333],"56":[0.00050799999999999999,0.0005202638888888889,0.00054512500000000004],"98304":[0.100110833,0.10291012500000002,0.10484758399999999],"64":[0.00051754199999999996,0.00052133300000000002,0.00052375878947368427],"131072":[0.13411058300000001,0.13490387500000001,0.13567254100000001],"20480":[0.022655999999999999,0.023440499999999975,0.023563000000000001],"80":[0.00051141700000000001,0.00051258300000000005,0.00053436344444444451],"1":[0.0031246659999999999,0.0031493329999999998,0.003230354],"2":[0.001626583,0.0016400138333333332,0.0016412361666666667],"768":[0.0012438988571428571,0.001273167,0.0012821250000000001],"3":[0.0011415419999999999,0.0011423749999999999,0.0011485],"4":[0.00084620799999999999,0.00088211736363636361,0.00089341699999999997],"320":[0.00071757053846153844,0.00079679100000000004,0.000845417],"5":[0.00071891700000000002,0.00072887500000000003,0.00075483683333333338],"6":[0.00063404200000000003,0.00063487500000000002,0.00063783299999999998],"10240":[0.010942834,0.011426125000000001,0.011752979],"7":[0.00059483400000000003,0.00059829200000000005,0.00061420799999999998],"24576":[0.026265,0.026999270499999999,0.027724624999999999],"10":[0.00061050000000000004,0.00062683886666666671,0.00063485560000000002],"8":[0.00054404200000000001,0.00054774999999999995,0.00055037499999999997],"896":[0.001269416,0.0014478958333333334,0.0015026250000000001],"163840":[0.16109264600000001,0.17002733400000003,0.17136470849999999],"3584":[0.0045612500000000002,0.0045612910000000003,0.0045661874999999999],"40960":[0.042850332999999997,0.044413833,0.045134708000000003],"1536":[0.0019310830000000001,0.0021695830000000001,0.0021956562500000001],"12":[0.00059154687499999995,0.00059670800000000005,0.00060353381249999996],"2560":[0.0032495204999999998,0.003286583,0.003344292],"65536":[0.066597792000000003,0.068808707999999996,0.068827708500000001],"229376":[0.22839989599999999,0.23605470849999999,0.23642439600000001],"512":[0.000921458,0.00097383300000000001,0.00097820799999999994],"20":[0.000535875,0.00054149999999999999,0.00055062500000000001],"81920":[0.085261583000000002,0.086396834000000006,0.086696562500000018],"14336":[0.015700540999999998,0.015786103999999999,0.016093708000000002],"14":[0.00054191600000000003,0.00054512500000000004,0.00055162500000000003],"96":[0.00051804100000000001,0.00053633299999999995,0.00053989355555555561],"12288":[0.013605604,0.013753792000000001,0.014380958500000001],"128":[0.00055320800000000002,0.00056346082352941177,0.00058825000000000001],"49152":[0.052115896000000002,0.052190124999999997,0.052350500000000001],"16":[0.00054466699999999998,0.00054750000000000003,0.00056508299999999997],"640":[0.001049375,0.0010852920000000001,0.001130792],"192":[0.00061637499999999995,0.00062545799999999996,0.00063266699999999995],"24":[0.00050958299999999998,0.00052058300000000003,0.00053637499999999996],"4096":[0.0049125840000000002,0.0049830830000000001,0.0051416669999999999],"32":[0.00054166666666666664,0.00055156617647058822,0.00055566700000000003],"2048":[0.0025109590000000001,0.002753430666666667,0.002821736],"256":[0.00065387500000000005,0.00068037499999999999,0.00068951041666666672],"3072":[0.0035162499999999998,0.0036856660000000002,0.0038728339999999999],"1792":[0.0021969170000000001,0.0024740000000000001,0.0026285696666666545],"40":[0.000486875,0.00052012499999999997,0.00052955783333333327],"28672":[0.0312381875,0.032218416499999999,0.0322380835],"1024":[0.0014872920000000001,0.001617666,0.0017694169999999999],"262144":[0.2519811455,0.261303375,0.26257820850000002],"7168":[0.0085161660000000004,0.0085620409999999994,0.0086204999999999997],"8192":[0.0092880830000000008,0.0095294585000000008,0.0098855839999999993],"28":[0.00051587499999999995,0.00054004425000000003,0.00058358399999999995],"32768":[0.033873583499999999,0.033974645499999997,0.035672874999999993],"6144":[0.007213583,0.0072567919999999998,0.0074128329999999997],"384":[0.00086141699999999996,0.00087545899999999998,0.00090429200000000001],"160":[0.00057233350000000002,0.00057295899999999995,0.00061344166666666669],"5120":[0.0061128329999999998,0.006114792,0.0064352919999999996],"448":[0.00093483399999999995,0.00094225000000000005,0.0010155138888888889],"114688":[0.11534375000000002,0.11775316700000001,0.12281854199999998],"16384":[0.018059416499999981,0.018479479,0.0188844375],"112":[0.00053354200000000002,0.00053649999999999998,0.00053809261111111115],"224":[0.000631417,0.00065395899999999996,0.00067520799999999995],"196608":[0.19478891700000001,0.200051271,0.2018585]}}]} -------------------------------------------------------------------------------- /BenchmarkData/chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ole/ConcurrencyBenchmark/04dcd7fec619ed58c4ec57fd425bc0640c4541fd/BenchmarkData/chart.png -------------------------------------------------------------------------------- /Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "pins" : [ 3 | { 4 | "identity" : "swift-argument-parser", 5 | "kind" : "remoteSourceControl", 6 | "location" : "https://github.com/apple/swift-argument-parser", 7 | "state" : { 8 | "revision" : "6b2aa2748a7881eebb9f84fb10c01293e15b52ca", 9 | "version" : "0.5.0" 10 | } 11 | }, 12 | { 13 | "identity" : "swift-collections-benchmark", 14 | "kind" : "remoteSourceControl", 15 | "location" : "https://github.com/apple/swift-collections-benchmark", 16 | "state" : { 17 | "revision" : "665cbb154a55f45bcedd2ab4faf17b1b7ac06de3", 18 | "version" : "0.0.2" 19 | } 20 | }, 21 | { 22 | "identity" : "swift-system", 23 | "kind" : "remoteSourceControl", 24 | "location" : "https://github.com/apple/swift-system", 25 | "state" : { 26 | "revision" : "39774ef16a6d91dee6f666b940e00ea202710cf7", 27 | "version" : "0.0.3" 28 | } 29 | } 30 | ], 31 | "version" : 2 32 | } 33 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version: 5.7 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "ConcurrencyBenchmark", 8 | platforms: [.macOS(.v12)], 9 | products: [ 10 | // Products define the executables and libraries a package produces, and make them visible to other packages. 11 | .executable(name: "benchmark", targets: ["BenchmarkCLI"]), 12 | .library( 13 | name: "Computation", 14 | targets: ["Computation"] 15 | ), 16 | ], 17 | dependencies: [ 18 | // Dependencies declare other packages that this package depends on. 19 | // .package(url: /* package url */, from: "1.0.0"), 20 | .package(url: "https://github.com/apple/swift-collections-benchmark", from: "0.0.2"), 21 | ], 22 | targets: [ 23 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 24 | // Targets can depend on other targets in this package, and on products in packages this package depends on. 25 | .executableTarget( 26 | name: "BenchmarkCLI", 27 | dependencies: [ 28 | "Computation", 29 | .product(name: "CollectionsBenchmark", package: "swift-collections-benchmark"), 30 | ] 31 | ), 32 | .target( 33 | name: "Computation", 34 | dependencies: [] 35 | ), 36 | .testTarget( 37 | name: "ComputationTests", 38 | dependencies: ["Computation"] 39 | ), 40 | ] 41 | ) 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ConcurrencyBenchmark 2 | 3 | Benchmarks for CPU-bound computation comparing different parallelization strategies. 4 | 5 | ## Usage 6 | 7 | Run the benchmarks: 8 | 9 | ```sh 10 | swift run -c release benchmark run \ 11 | --cycles 3 \ 12 | --max-size 256k \ 13 | BenchmarkData/benchmark-data.json 14 | ``` 15 | 16 | Create a chart: 17 | 18 | ```sh 19 | swift run -c release benchmark render \ 20 | BenchmarkData/benchmark-data.json \ 21 | BenchmarkData/chart.png \ 22 | --amortized false 23 | ``` 24 | 25 | For more options: 26 | - See the [Swift Collections Benchmark Getting Started Guide](https://github.com/apple/swift-collections-benchmark/blob/main/Documentation/01%20Getting%20Started.md) 27 | - `swift run -c release benchmark run --help` 28 | - `swift run -c release benchmark render --help` 29 | 30 | ## Analysis 31 | 32 | This chart was created on an Apple M1 Pro (10 cores): 33 | 34 | ![Current chart](BenchmarkData/chart.png) 35 | 36 | Note: the x axis should be called "number of subtasks", not "input size": 37 | 38 | - The benchmark always performs 10 million computations (this is [the `totalWorkload` variable](https://github.com/ole/ConcurrencyBenchmark/blob/main/Sources/BenchmarkCLI/Main.swift#L5) in the code) 39 | - If "input size" = 10, the workload is split into 10 "subtasks". E.g. we're calling `concurrentPerform` with 10 iterations, where each iteration perform 10 million / 10 = 1 million computations. Same for the `TaskGroup` (10 child tasks) and `DispatchQueue.global.async()` (10 work items passed to the global queue) benchmarks. 40 | - For large input sizes, this creates a very large number of subtasks with each subtask doing very little work. This is why the curves go up as the number of subtasks increases. 41 | - The "No parallelism (1 core)" task always performs the same number of computations, regardless of input size. This is why the line is flat. 42 | - We're passing `--amortized false` when rendering the chart to show the total elapsed time. Without this, the chart would depict the time per "subtask", which is meaningless to us because the amount of work per subtask isn't constant. 43 | 44 | Observations: 45 | 46 | - The pure computational work takes ~3 ms on this machine (see the flat line). 47 | - At 1 subtask (no parallelism), all strategies have effectively the same performance (as expected). 48 | - At the optimal level of parallelism (around 32–64 subtasks), all parallelization strategies are are almost 10× as fast as the single-core benchmark (as expected). 49 | - `DispatchQueue.concurrentPerform` is more efficient than `TaskGroup` and `DispatchQueue.global().async` as the number of subtasks increases. 50 | -------------------------------------------------------------------------------- /Sources/BenchmarkCLI/Main.swift: -------------------------------------------------------------------------------- 1 | import CollectionsBenchmark 2 | import Computation 3 | import Dispatch 4 | 5 | let totalWorkload = 10_000_000 6 | 7 | @main 8 | struct Main { 9 | static func main() { 10 | var benchmark = Benchmark(title: "Fibonacci") 11 | 12 | benchmark.addSimple(title: "No parallelism (1 core)", input: Int.self) { input in 13 | blackHole(performWork_syncSingleCore(taskCount: input)) 14 | } 15 | benchmark.addSimple(title: "concurrentPerform", input: Int.self) { input in 16 | blackHole(performWork_concurrentPerform(taskCount: input)) 17 | } 18 | 19 | benchmark.addSimple(title: "DispatchQueue.global().async", input: Int.self) { input in 20 | blackHole(performWork_dispatchQueueGlobalAsync(taskCount: input)) 21 | } 22 | 23 | benchmark.addSimple(title: "TaskGroup", input: Int.self) { input in 24 | blackHole(performWork_taskGroup(taskCount: input)) 25 | } 26 | 27 | benchmark.main() 28 | } 29 | } 30 | 31 | /// - Parameter taskCount: The number of "subtasks" the workload should be split into. 32 | /// The total amount of work remains constant, regardless of input. 33 | func performWork_syncSingleCore(taskCount: Int) { 34 | for _ in 0 ..< taskCount { 35 | _ = fibonacciOverflow(totalWorkload / taskCount) 36 | } 37 | } 38 | 39 | /// - Parameter taskCount: The number of "subtasks" the workload should be split into. 40 | /// The total amount of work remains constant, regardless of input. 41 | func performWork_concurrentPerform(taskCount: Int) { 42 | DispatchQueue.concurrentPerform(iterations: taskCount) { i in 43 | _ = fibonacciOverflow(totalWorkload / taskCount) 44 | } 45 | } 46 | 47 | /// - Parameter taskCount: The number of "subtasks" the workload should be split into. 48 | /// The total amount of work remains constant, regardless of input. 49 | func performWork_dispatchQueueGlobalAsync(taskCount: Int) { 50 | let dispatchGroup = DispatchGroup() 51 | for _ in 0 ..< taskCount { 52 | DispatchQueue.global().async(group: dispatchGroup) { 53 | _ = fibonacciOverflow(totalWorkload / taskCount) 54 | } 55 | } 56 | dispatchGroup.wait() 57 | } 58 | 59 | /// - Parameter taskCount: The number of "subtasks" the workload should be split into. 60 | /// The total amount of work remains constant, regardless of input. 61 | func performWork_taskGroup(taskCount: Int) { 62 | let dispatchGroup = DispatchGroup() 63 | dispatchGroup.enter() 64 | 65 | let work = _Concurrency.Task.detached { 66 | await withTaskGroup(of: Void.self) { group in 67 | for _ in 0 ..< taskCount { 68 | group.addTask { 69 | _ = fibonacciOverflow(totalWorkload / taskCount) 70 | } 71 | } 72 | for await _ in group {} 73 | } 74 | } 75 | 76 | // Wait for async work from sync context. 77 | _Concurrency.Task.detached { 78 | _ = await work.value 79 | dispatchGroup.leave() 80 | } 81 | dispatchGroup.wait() 82 | } 83 | -------------------------------------------------------------------------------- /Sources/Computation/Fibonacci.swift: -------------------------------------------------------------------------------- 1 | public func fibonacciOverflow(_ n: Int) -> Int { 2 | var a = 0 3 | var b = 1 4 | for _ in 0 ..< n { 5 | let tmp = b 6 | b = a &+ b 7 | a = tmp 8 | } 9 | return a 10 | } 11 | -------------------------------------------------------------------------------- /Tests/ComputationTests/ConcurrencyBenchmarkTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import Computation 3 | 4 | final class ComputationTests: XCTestCase { 5 | func testExample() throws { 6 | } 7 | } 8 | --------------------------------------------------------------------------------