From 4408e2f4e2b0d56ab6763a6aba12f65eeac642c0 Mon Sep 17 00:00:00 2001 From: cxl Date: Mon, 8 Jan 2018 09:47:49 +0000 Subject: [PATCH] .tutorial git-svn-id: svn://ultimatepp.org/upp/trunk@11670 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/Core/srcdoc.tpp/Tutorial_en-us.tpp | 182 +++++++++++++--------- uppsrc/ide/icon.ico | Bin 2862 -> 2862 bytes 2 files changed, 107 insertions(+), 75 deletions(-) diff --git a/uppsrc/Core/srcdoc.tpp/Tutorial_en-us.tpp b/uppsrc/Core/srcdoc.tpp/Tutorial_en-us.tpp index 0bf900da2..ec77b4c10 100644 --- a/uppsrc/Core/srcdoc.tpp/Tutorial_en-us.tpp +++ b/uppsrc/Core/srcdoc.tpp/Tutorial_en-us.tpp @@ -80,8 +80,9 @@ topic "U++ Core Tutorial"; [s0; ___[^`#Section`_7`_4^ 7.4 CoWork]&] [s0; ___[^`#Section`_7`_5^ 7.5 AsyncWork]&] [s0; ___[^`#Section`_7`_6^ 7.6 CoPartition]&] -[s0; ___[^`#Section`_7`_7^ 7.7 Parallel algorithms]&] -[s0;^`#Section`_7`_7^ &] +[s0; ___[^`#Section`_7`_7^ 7.7 CoWork loop method]&] +[s0; ___[^`#Section`_7`_8^ 7.8 Parallel algorithms]&] +[s0;^`#Section`_7`_8^ &] [s22;:Chapter`_1: 1. Basics&] [s3;:Section`_1`_1: 1.1 Logging&] [s5; Logging is a useful technique to trace the flow of the code @@ -124,8 +125,8 @@ variable name and value:&] [s7; DUMPHEX(h);&] [s0; &] [s17; x `= 0x7b&] -[s17; h `= Memory at 0x01FEF7A0, size 0x3 `= 3&] -[s17; `+0 0x01FEF7A0 66 6F 6F +[s17; h `= Memory at 0x0218FDB4, size 0x3 `= 3&] +[s17; `+0 0x0218FDB4 66 6F 6F foo &] [s0; &] [s5; To log the value of a container (or generic Range), you can @@ -369,8 +370,8 @@ data, including zeroes:&] [s7; &] [s7; DUMPHEX(a);&] [s0; &] -[s17; a `= Memory at 0x01FEF800, size 0x5 `= 5&] -[s17; `+0 0x01FEF800 31 32 33 34 00 +[s17; a `= Memory at 0x0218FE14, size 0x5 `= 5&] +[s17; `+0 0x0218FE14 31 32 33 34 00 1234. &] [s0; &] [s3;H4;:Section`_1`_3: 1.3 StringBuffer&] @@ -473,7 +474,7 @@ concrete types.&] [s7; &] [s7; DUMP(date);&] [s0; &] -[s17; date `= 12/16/2017&] +[s17; date `= 01/08/2018&] [s0; &] [s5; All data members of [*C@5 Date] structure are public:&] [s0; &] @@ -483,9 +484,9 @@ date members&] would log&] [s7; DUMP((int)date.day); // as characters&] [s0; &] -[s17; (int)date.year `= 2017&] -[s17; (int)date.month `= 12&] -[s17; (int)date.day `= 16&] +[s17; (int)date.year `= 2018&] +[s17; (int)date.month `= 1&] +[s17; (int)date.day `= 8&] [s0; &] [s5; Dates can be compared:&] [s0; &] @@ -500,15 +501,15 @@ ing goes to the next/previous day:&] [s7; DUMP(`-`-date);&] [s7; DUMP(`+`+date);&] [s0; &] -[s17; date `+ 1 `= 12/17/2017&] -[s17; `-`-date `= 12/15/2017&] -[s17; `+`+date `= 12/16/2017&] +[s17; date `+ 1 `= 01/09/2018&] +[s17; `-`-date `= 01/07/2018&] +[s17; `+`+date `= 01/08/2018&] [s0; &] [s5; Subtraction of dates yields a number of days between them:&] [s0; &] [s7; DUMP(date `- Date(2000, 1, 1));&] [s0; &] -[s17; date `- Date(2000, 1, 1) `= 6559&] +[s17; date `- Date(2000, 1, 1) `= 6582&] [s0; &] [s5; There are several [*C@5 Date] and calendar related functions:&] [s0; &] @@ -534,7 +535,7 @@ ing goes to the next/previous day:&] [s0; &] [s7; DUMP(DayOfWeek(date)); // 0 is Sunday&] [s0; &] -[s17; DayOfWeek(date) `= 6&] +[s17; DayOfWeek(date) `= 1&] [s0; &] [s0; &] [s7; DUMP(LastDayOfMonth(date));&] @@ -544,11 +545,11 @@ ing goes to the next/previous day:&] [s7; DUMP(DayOfYear(date)); // number of days since Jan`-1 `+ 1&] [s7; DUMP(DayOfYear(Date(2016, 1, 1)));&] [s0; &] -[s17; LastDayOfMonth(date) `= 12/31/2017&] -[s17; FirstDayOfMonth(date) `= 12/01/2017&] -[s17; LastDayOfYear(date) `= 12/31/2017&] -[s17; FirstDayOfYear(date) `= 01/01/2017&] -[s17; DayOfYear(date) `= 350&] +[s17; LastDayOfMonth(date) `= 01/31/2018&] +[s17; FirstDayOfMonth(date) `= 01/01/2018&] +[s17; LastDayOfYear(date) `= 12/31/2018&] +[s17; FirstDayOfYear(date) `= 01/01/2018&] +[s17; DayOfYear(date) `= 8&] [s17; DayOfYear(Date(2016, 1, 1)) `= 1&] [s0; &] [s0; &] @@ -559,10 +560,10 @@ between two dates&] partial months`' between two dates&] [s7; DUMP(AddYears(date, 2));&] [s0; &] -[s17; AddMonths(date, 20) `= 08/16/2019&] +[s17; AddMonths(date, 20) `= 09/08/2019&] [s17; GetMonths(date, date `+ 100) `= 3&] [s17; GetMonthsP(date, date `+ 100) `= 4&] -[s17; AddYears(date, 2) `= 12/16/2019&] +[s17; AddYears(date, 2) `= 01/08/2020&] [s0; &] [s0; &] [s7; DUMP(GetWeekDate(2015, 1));&] @@ -602,11 +603,11 @@ time:&] [s7; DUMP((int)time.minute);&] [s7; DUMP((int)time.second);&] [s0; &] -[s17; time `= 12/16/2017 14:21:41&] -[s17; (Date)time `= 12/16/2017&] -[s17; (int)time.hour `= 14&] -[s17; (int)time.minute `= 21&] -[s17; (int)time.second `= 41&] +[s17; time `= 01/08/2018 10:46:53&] +[s17; (Date)time `= 01/08/2018&] +[s17; (int)time.hour `= 10&] +[s17; (int)time.minute `= 46&] +[s17; (int)time.second `= 53&] [s0; &] [s5; Times can be compared:&] [s0; &] @@ -633,10 +634,10 @@ but numbers represent seconds (using [*C@5 int64] datatype):&] is in days&] [s7; DUMP(time `- ToTime(date)); // Time `- Time is in seconds&] [s0; &] -[s17; time `+ 1 `= 12/16/2017 14:21:42&] -[s17; time `+ 24 `* 3600 `= 12/17/2017 14:21:41&] +[s17; time `+ 1 `= 01/08/2018 10:46:54&] +[s17; time `+ 24 `* 3600 `= 01/09/2018 10:46:53&] [s17; time `- date `= 0&] -[s17; time `- ToTime(date) `= 51701&] +[s17; time `- ToTime(date) `= 38813&] [s0; &] [s5; [*C@5 Time] defines era limits too:&] [s0; &] @@ -691,9 +692,9 @@ items predefined by U`+`+:&] [s7; DUMP(LoadFile(ConfigFile(`"test.txt`")));&] [s7; DUMP(sout);&] [s0; &] -[s17; LoadFile(ConfigFile(`"test.txt`")) `= 1.23 12/16/2017 12/16/2017 -14:21:41&] -[s17; sout `= 1.23 12/16/2017 12/16/2017 14:21:41&] +[s17; LoadFile(ConfigFile(`"test.txt`")) `= 1.23 01/08/2018 01/08/2018 +10:46:53&] +[s17; sout `= 1.23 01/08/2018 01/08/2018 10:46:53&] [s0; &] [s5; Getting client types involved into this schema is not too difficult, all you need to do is to add [*C@5 ToString] method:&] @@ -1068,8 +1069,8 @@ in both little`-endian and big`-endian modes:&] [s7; ss.Put32be(0x12345678);&] [s7; DUMPHEX(ss.GetResult());&] [s0; &] -[s17; ss.GetResult() `= Memory at 0x01FEF2D0, size 0x8 `= 8&] -[s17; `+0 0x01FEF2D0 78 56 34 12 12 34 56 78 +[s17; ss.GetResult() `= Memory at 0x0218F8E4, size 0x8 `= 8&] +[s17; `+0 0x0218F8E4 78 56 34 12 12 34 56 78 xV4..4Vx &] [s0; &] [s0; &] @@ -1118,11 +1119,11 @@ them via [*C@5 Out] virtual method:&] [s7; os << `"This is a test `" << 12345;&] [s7; os.Close();&] [s0; &] -[s17; String((const char `*)data, size) `= Memory at 0x07B71DD0, size +[s17; String((const char `*)data, size) `= Memory at 0x07CE1DD0, size 0x14 `= 20&] -[s17; `+0 0x07B71DD0 54 68 69 73 20 69 73 20 61 20 74 65 73 74 +[s17; `+0 0x07CE1DD0 54 68 69 73 20 69 73 20 61 20 74 65 73 74 20 31 This is a test 1&] -[s17; `+16 0x07B71DE0 32 33 34 35 +[s17; `+16 0x07CE1DE0 32 33 34 35 2345 &] [s0; &] [s5; [*C@5 TeeStream] sends output data to two separate streams:&] @@ -1146,11 +1147,11 @@ block to stream data:&] [s7; while(!ms.IsEof())&] [s7; -|DUMPHEX(ms.GetLine());&] [s0; &] -[s17; ms.GetLine() `= Memory at 0x01FEF154, size 0x9 `= 9&] -[s17; `+0 0x01FEF154 53 6F 6D 65 20 6C 69 6E 65 +[s17; ms.GetLine() `= Memory at 0x0218F768, size 0x9 `= 9&] +[s17; `+0 0x0218F768 53 6F 6D 65 20 6C 69 6E 65 Some line &] -[s17; ms.GetLine() `= Memory at 0x01FEF154, size 0xC `= 12&] -[s17; `+0 0x01FEF154 41 6E 6F 74 68 65 72 20 6C 69 6E 65 +[s17; ms.GetLine() `= Memory at 0x0218F768, size 0xC `= 12&] +[s17; `+0 0x0218F768 41 6E 6F 74 68 65 72 20 6C 69 6E 65 Another line &] [s0; &] [s3;H4;:Section`_2`_3: 2.3 Binary serialization&] @@ -1395,7 +1396,7 @@ value.&] [s7; &] [s7; DUMP(v);&] [s0; &] -[s17; v `= `[987, 1030, 989, 997, 1012, 948, 1020, 1029, 989, 999`]&] +[s17; v `= `[987, 1039, 1032, 958, 1008, 986, 960, 1083, 988, 959`]&] [s0; &] [s5; You can apply algorithms on containers, e.g. Sort&] [s0; &] @@ -1403,7 +1404,7 @@ value.&] [s7; &] [s7; DUMP(v);&] [s0; &] -[s17; v `= `[948, 987, 989, 989, 997, 999, 1012, 1020, 1029, 1030`]&] +[s17; v `= `[958, 959, 960, 986, 987, 988, 1008, 1032, 1039, 1083`]&] [s0; &] [s3;H4;:Section`_3`_3: 3.3 Transfer issues&] [s5; Often you need to pass content of one container to another of @@ -1509,15 +1510,15 @@ to it:&] [s7; DUMPC(dist);&] [s0; &] [s17; dist:&] -[s17; -|`[0`] `= Test 5: `[1954, 1988, 2018, 1994, 2046`]&] -[s17; -|`[1`] `= Test 6: `[1666, 1671, 1624, 1654, 1721, 1664`]&] -[s17; -|`[2`] `= Test 7: `[1420, 1480, 1472, 1393, 1401, 1412, 1422`]&] -[s17; -|`[3`] `= Test 8: `[1303, 1235, 1252, 1196, 1197, 1285, 1254, -1278`]&] -[s17; -|`[4`] `= Test 9: `[1139, 1062, 1164, 1133, 1048, 1125, 1117, -1128, 1084`]&] -[s17; -|`[5`] `= Test 10: `[973, 983, 1024, 981, 1000, 1037, 979, 1032, -995, 996`]&] +[s17; -|`[0`] `= Test 5: `[1998, 1997, 2042, 2021, 1942`]&] +[s17; -|`[1`] `= Test 6: `[1648, 1606, 1676, 1732, 1692, 1646`]&] +[s17; -|`[2`] `= Test 7: `[1476, 1360, 1446, 1415, 1452, 1426, 1425`]&] +[s17; -|`[3`] `= Test 8: `[1208, 1272, 1251, 1245, 1248, 1202, 1300, +1274`]&] +[s17; -|`[4`] `= Test 9: `[1130, 1098, 1101, 1042, 1104, 1149, 1111, +1154, 1111`]&] +[s17; -|`[5`] `= Test 10: `[956, 992, 1005, 1008, 1056, 979, 964, 1054, +948, 1038`]&] [s0; &] [s5; Another possibility is to use [*C@5 Vector`::Add(T`&`&)] method, which uses pick`-constructor instead of deep`-copy constructor. @@ -2682,11 +2683,11 @@ is for the most part seamless:&] [s0; &] [s17; a `= 1&] [s17; b `= 2.34&] -[s17; c `= 12/16/2017&] +[s17; c `= 01/08/2018&] [s17; d `= hello&] [s17; x `= 1&] [s17; y `= 2.34&] -[s17; z `= 12/16/2017&] +[s17; z `= 01/08/2018&] [s17; s `= hello&] [s0; &] [s5; As for primitive types, Value seamlessly works with [*C@5 int], @@ -2718,7 +2719,7 @@ as it is supported by these types):&] [s0; &] [s17; i `= 1&] [s17; j `= 2&] -[s17; k `= 12/16/2017 00:00:00&] +[s17; k `= 01/08/2018 00:00:00&] [s17; t `= hello&] [s0; &] [s5; To determine type of value stored in [*C@5 Value], you can use @@ -3347,14 +3348,14 @@ thread to [*C@5 Wait] for its completion:&] [s17; In the thread 0&] [s17; In the main thread 1&] [s17; In the thread 1&] -[s17; In the main thread 2&] [s17; In the thread 2&] -[s17; In the thread 3&] +[s17; In the main thread 2&] [s17; In the main thread 3&] +[s17; In the thread 3&] [s17; In the thread 4&] [s17; In the main thread 4&] -[s17; About to wait for thread to finish&] [s17; In the thread 5&] +[s17; About to wait for thread to finish&] [s17; In the thread 6&] [s17; In the thread 7&] [s17; In the thread 8&] @@ -3402,7 +3403,7 @@ code demonstrates why:&] [s7; t.Wait();&] [s7; DUMP(sum);&] [s0; &] -[s17; sum `= 1031155&] +[s17; sum `= 1087631&] [s0; &] [s5; While the expected value is 2000000, produced value is different. The problem is that both thread read / modify / write [*C@5 sum] @@ -3527,13 +3528,13 @@ testing data&] [s7; DUMP(w);&] [s0; &] [s17; w `= `[Lorem, ipsum, dolor, sit, amet, consectetur, adipiscing, -elit, aliqua, Ut, enim, ad, minim, veniam, quis, nostrud, exercitation, -sed, do, eiusmod, tempor, incididunt, ut, labore, et, dolore, -magna, esse, cillum, eu, fugiat, nulla, pariatur, Excepteur, -Duis, aute, irure, in, reprehenderit, voluptate, velit, officia, -deserunt, mollit, anim, id, est, laborum, ullamco, laboris, nisi, -aliquip, ex, ea, commodo, consequat, sint, occaecat, cupidatat, -non, proident, sunt, culpa, qui`]&] +elit, sed, do, eiusmod, tempor, incididunt, ut, labore, et, dolore, +magna, Duis, aute, irure, in, reprehenderit, voluptate, velit, +officia, deserunt, mollit, anim, id, est, laborum, sint, occaecat, +cupidatat, non, proident, sunt, culpa, qui, aliqua, Ut, enim, +ad, minim, veniam, quis, nostrud, exercitation, esse, cillum, +eu, fugiat, nulla, pariatur, Excepteur, ullamco, laboris, nisi, +aliquip, ex, ea, commodo, consequat`]&] [s0; &] [s5; Adding words to [*C@5 w] requires [*C@5 Mutex]. Alternative to this `'result gathering`' [*C@5 Mutex] is [*C@5 CoWork`::FinLock]. The @@ -3561,13 +3562,13 @@ end of CoWork job&] [s7; DUMP(w);&] [s0; &] [s17; w `= `[Lorem, ipsum, dolor, sit, amet, consectetur, adipiscing, -elit, aliqua, Ut, enim, ad, minim, veniam, quis, nostrud, exercitation, -sed, do, eiusmod, tempor, incididunt, ut, labore, et, dolore, -magna, esse, cillum, eu, fugiat, nulla, pariatur, Excepteur, -Duis, aute, irure, in, reprehenderit, voluptate, velit, officia, -deserunt, mollit, anim, id, est, laborum, ullamco, laboris, nisi, -aliquip, ex, ea, commodo, consequat, sint, occaecat, cupidatat, -non, proident, sunt, culpa, qui`]&] +elit, sed, do, eiusmod, tempor, incididunt, ut, labore, et, dolore, +magna, Duis, aute, irure, in, reprehenderit, voluptate, velit, +officia, deserunt, mollit, anim, id, est, laborum, sint, occaecat, +cupidatat, non, proident, sunt, culpa, qui, aliqua, Ut, enim, +ad, minim, veniam, quis, nostrud, exercitation, esse, cillum, +eu, fugiat, nulla, pariatur, Excepteur, ullamco, laboris, nisi, +aliquip, ex, ea, commodo, consequat`]&] [s0; &] [s5; Of course, the code performed after [*C@5 FinLock] should not take long, otherwise there is negative impact on all [*C@5 CoWork] @@ -3758,7 +3759,38 @@ h) `{&] [s0; &] [s17; sum `= 49995000&] [s0; &] -[s3;H4;:Section`_7`_7: 7.7 Parallel algorithms&] +[s3;H4;:Section`_7`_7: 7.7 CoWork loop method&] +[s5; An alternative to [*C@5 CoPartition] is `'loop`' method of [*C@5 CoWork] +([*C@5 Loop] method with synonym [*C@5 operator`*]). In this pattern, +the job is simply started in all threads and the code is responsible +for scheduling the work. [*C@5 Loop] / [*C@5 operator`*] waits for +all started threads to finish. For scheduling, it is possible +to use internal [*C@5 CoWork] index counter, which is set to 0 +at the start of [*C@5 Loop] / [*C@5 operator`*]. This way, the overhead +associated with creating lambdas and scheduling them is kept +to the minimum.&] +[s0; &] +[s7; Vector data;&] +[s7; for(int i `= 0; i < 100; i`+`+)&] +[s7; -|data.Add(AsString(1.0 / i));&] +[s7; &] +[s7; double sum `= 0;&] +[s7; &] +[s7; CoWork co;&] +[s7; co `* `[`&`] `{&] +[s7; -|int i;&] +[s7; -|double m `= 0;&] +[s7; -|while((i `= co.Next()) < data.GetCount())&] +[s7; -|-|m `+`= atof(data`[i`]);&] +[s7; -|CoWork`::FinLock();&] +[s7; -|sum `+`= m;&] +[s7; `};&] +[s7; &] +[s7; DUMP(sum);&] +[s0; &] +[s17; sum `= 1e299&] +[s0; &] +[s3;H4;:Section`_7`_8: 7.8 Parallel algorithms&] [s5; U`+`+ provides a parallel versions of algorithms where it makes sense. The naming scheme is `'Co`' prefix before the name of algorithm designates the parallel version.&] diff --git a/uppsrc/ide/icon.ico b/uppsrc/ide/icon.ico index bf7396000c5a5bbd881ef50e8aa1394ab2eb92b1..040ff9398378bc29f4ed954a4a70bda2328324d6 100644 GIT binary patch literal 2862 zcmcguJ+9O+5T2~FS)1x{0#-DkqN>GRba7-9I`)0jJv|i zep18rW)oWxvs|=nMAA8D=gr*+r{!Q71vNQ|=PEe|7tU(n8@SFTenm2a)SkshKI==Z zPB7t*)D$hC&or^fQ~8`fF@NwJ$Kw@(7w5eIFC?*E=K!qYkxR2FJJ)sWS!ad)P@6e& zTzWag*O3Fhy5JfJ1*$b6^^YzX;X~xTJ1Re4DYN9(dz`U*_1a z1+z8C438ieOU}3}aLiksS^>l!6hF@w9O<0(d5r^j%N6r5idnA6OJCslH$3K%dp@^+ zS(n!~&&-i?5@R>X!TjUs(0=TLZ?pJr6DlvRg4e50_tQCItv+(aZ1c{#n$3zs>75uJ zu|gGf@)<6Z&bd_RnkICe3v5LEFoa##g(3O~?slCfLvSpi-|etKO#OcD4}EWW!3{%i z_yGQv)%eA43*YC~P0E1#Kp^A`a_vHjT$ew{2iy-_>mp71 zboV8JfHH4n$y%N5b;#x524+Vyn)mcHUW|z zhgsn~^o|^3U9{ZBmz7(5Wy4+MxY_R~M7i5}(o9SpFaKXS;Uo)>*4mYE)I_+EzIZV%8Yfw5>Bkj$+faVbeLq=IW-w0=1CW z`?;y>xGy+k>WFvX*X)sBa-HSYI;FL