I believe many coders have seen small jokes (such as me) such as "life is short, use Python", which is not unreasonable. Each programming language has its own advantages and disadvantages.
Programmers have also learned more than one language, such as me.
Hu has touched N languages like me, but he is barely familiar with two or three of them (C ++, C #, Delphi, and Golang ), but I still want to compare them in a shortest.
Starting from the example we can see by chance.
Uses SyncObjs, System. threading, System. diagnostics; {function local to the unit} function IsPrime (N: Integer): Boolean; var Test: Integer; begin IsPrime: = True; for Test: = 2 to N-1 do if (N mod Test) = 0 then begin IsPrime: = False; break; {jump out of the for loop} end; const Max = 100000; // 100 Kprocedure TFormParallelFor. btnPlainForLoopClick (Sender: TObject); var I, Tot: Integer; Ticks: Cardinal; begin // counts the prime numbers below a given value Tot: = 0; Ticks: = GetTickCount; for I: = 1 to Max do begin if IsPrime (I) then Inc (Tot); // Application. processMessages; end; Ticks: = GetTickCount-Ticks; Memo1.Lines. add (Format ('plain for: % d-% d', [Ticks, Tot]); end; procedure TFormParallelFor. btnParallelForLoopClick (Sender: TObject); var Tot: Integer; Ticks: Cardinal; begin Tot: = 0; Ticks: = GetTickCount; TParallel. for (1, Max, procedure (I: Int64) begin if IsPrime (I) then InterlockedIncrement (Tot); end); Ticks: = GetTickCount-Ticks; Memo1.Lines. add (Format ('parallel for: % d-% d', [Ticks, Tot]); end;
Delphi XE7 introduces a new concurrent auxiliary library (which seems to be operated by Allen Bauer), which provides language support for multi-core programming. I saw this simple article during a visit to the Embarcadero Forum and learned that Delphi supports concurrency through its self-implemented auto scaling and intelligent thread pool, one of the definitions caught my attention: MaxThreadsPerCPU = 25 (of course I still don't know why the maximum number of threads hanging on each core is 25 ). I am too reluctant to download and install the huge XE7 to see the relevant RTL source code. However, since I just had an official Demo, I simply ran it as follows.
It seems that this parallel library is quite good.
So I felt a little itchy. I don't know what the speed would be if Golang was used for the same implementation? (Note: as you only want to test the goroutine and channel, the code does not use the functions provided by the atomic operation package sync/atomic. I am not familiar with OpenMP, so I have not compared it ).
// ParallelCalcDemo project main. gopackage mainimport ("fmt" "runtime" "time") const cNumMax = 100000 func IsPrime (num int) bool {ret: = truefor I: = 2; I <num; I ++ {if num % I = 0 {ret = falsebreak} return ret} func plainCalc () {cnt: = 0t1: = time. now () for I: = 1; I <= cNumMax; I ++ {if IsPrime (I) {cnt ++} t2: = time. now () fmt. printf ("plainCalc-Counts: % d; Time: % dms \ n", cnt, t2.Sub (t1)/time. millisecon D)} func parallelHandle (numMin, numMax int, ch chan int) {cnt: = 0for I: = numMin; I <= numMax; I ++ {if IsPrime (I) {cnt ++} ch <-cnt} func parallelCalc (numGoroutines int) {t1: = time. now () chans: = make (chan int, numGoroutines) seg: = cNumMax/numGoroutinesif cNumMax % numGoroutines! = 0 {seg ++} for I: = 0; I <numGoroutines-1; I ++ {go parallelHandle (1 + I * seg, (I + 1) * seg, chans)} go parallelHandle (1 + (numGoroutines-1) * seg, cNumMax, chans) cnt: = 0for I: = 0; I <numGoroutines; I ++ {cnt + = <-chans} t2: = time. now () fmt. printf ("parallelCalc-Counts: % d; Time: % dms \ n", cnt, t2.Sub (t1)/time. millisecond)} func parallelHandle2 (value int, ch chan int) {if IsPrime (value) {ch <-1 return} ch <-0} func parallelCalc2 () {t1: = time. now () chans: = make (chan int, cNumMax) for I: = 1; I <= cNumMax; I ++ {go parallelHandle2 (I, chans)} cnt: = 0for I: = 1; I <= cNumMax; I ++ {cnt ++ = <-chans} t2: = time. now () fmt. printf ("parallelCalc2-Counts: % d; Time: % dms \ n", cnt, t2.Sub (t1)/time. millisecond)} func main () {numGoroutines: = runtime. numCPU () runtime. GOMAXPROCS (numGoroutines) plainCalc () parallelCalc (numGoroutines) parallelCalc2 ()}
The result is as follows.
It can be seen that the efficiency is still acceptable, although it is several percentage points slower than the parallel version of Delphi. Since we mentioned the number 25 above, why not set GOMAXPROCS to runtime. NumCPU () * 25? If the previous code is slightly modified, the following result is displayed.
As a result, we found that the (parallel) efficiency seems to be a little higher than that before the modification, which is basically the same as the parallel version of Delphi. According to some information on the Internet, it seems that Golang's scheduler is not enough "NB ":)
Of course, for example, the implementation of parallelCalc2 may be due to the loss of Ding point scheduling efficiency caused by 100 K goroutines.
But even so, even through the simple code snippets above, we can still see that it is too convenient to implement concurrency in Golang, goroutine and channel are really cheap but concise and efficient concurrent tools. This feature is also very useful and important for server-side development, greatly simplifying the multi-thread logic on the server side. At the core layer of the language, it supports parallel and distributed features. The concurrency model is simple and efficient, and is a born back-end development tool.
For example, the following code snippet is a small embodiment of its power.
// SimpleTcpServer project main. gopackage mainimport ("fmt" "net" "strings") func main () {fmt. println ("Starting the server... ") listener, err: = net. listen ("tcp", "localhost: 50000") if err! = Nil {fmt. Println ("Error listening", err. Error () return} for {conn, err: = listener. Accept () if err! = Nil {fmt. println ("Error accepting", err. error () return} go doStuff (conn)} func doStuff (conn net. conn) {for {buf: = make ([] byte, 512) _, err: = conn. read (buf) if err! = Nil {fmt. println ("Error reading", err. error () return} fmt. printf ("Received data: % v", strings. trim (string (buf ),""))}}
So Golang is a little interesting, right?
When I first started learning Golang, it seemed that some of its "anti-humanity" syntax had made me quite uncomfortable (it is estimated that many coders will feel this way more or less ), but after getting familiar with it for a while, it was quite easy to see. Such as comma, OK form, type derivation (of course C ++ 11 has auto, C # also has this syntax feature), delayed execution, and other syntactic sugar features are indeed concise, but at the same time, it is powerful and practical, and is used to try .. catch/try... else t... similar codes such as finally are used to releasing resources by various means. When we encounter such concise syntaxes as comma, OK, and defer, will there be surprises or even complaints )?
By the way, try in C .. else t .. finally is similar to the related syntax of Delphi, but the difference is that the latter only has try .. before T and try .. finally, I have never joined the enhancement feature like the former, so I cannot figure it out.
We are used to entering/encountering so-called keywords such as private, public, and protected, and even worse, internal and protected internal. Golang only controls the access permission with the first case and case to achieve the same effect, not to mention the novelty and conciseness. Sometimes I think, for example, C ++/C # introduces a lot of syntactic sugar that does seem practical, but they are rarely or even rarely used, in addition, the vast majority can be implemented by users (I .e. coders) to improve their design methods. In this case, why should we introduce them, are they really good for so-called software engineering?
C ++ has so many syntax features, but I am wondering how much actually we use in actual development? Most of the time, we only use a small subset of it. The language complexity greatly increases the learning and usage costs, complicated and lengthy compilation processes, and the possibility of (unqualified) programmers abusing certain features. Even if it can generate very efficient (and compact) machine code, the cost is too large.
By the way, when it comes to private and public, the published feature of Delphi is indeed very useful and practical for writing UI-related programs, I believe that code farmers who have used Delphi will have some experience (C # code farmers are the same ).
Use C ++ for UI? Alas.
Getter/setter? How well property wraps them.
I tried to simulate the initialization and finalization features of Delphi in C ++, but I didn't do it well (of course, C ++ Builder has this feature ). But Golang provides init, and the detailed language design still brings me a lot of joy (Golang has GC, so finalization has little significance ).
Then, for example, code formatting is not a language feature. I personally feel more meaningful and practical, especially for coders who have so-called code cleanliness :)
Similarly, there is no need to end each line of code and other features, it is a bit practical, and the accumulation of these language features, in order to facilitate the use of its code farmers to write simple, intuitive code.
However, although Golang's goroutine/channel is powerful and concise, it still requires many practices and examples to understand and understand. For example, the following seemingly simple code is not "abstract ":)
// Primesieve project main. gopackage mainimport ("fmt") // Send the sequence 2, 3, 4 ,... to channel chfunc generate (ch chan int) {for I: = 2; I ++ {ch <-I }}// Copy the values from channel in to channel out, removing those divisible by primefunc filter (in, out chan int, prime int) {for {I: = <-inif I % prime! = 0 {out <-I }}func main () {ch: = make (chan int) go generate (ch) for {prime :=<-chfmt. print (prime, "") counts: = make (chan int) go filter (ch, counts, prime) ch = counts }}
However, since the role of goroutine/channel is so great, it is so simple to use and take the time spent on research on the technology and lust to learn and understand them, why not?
Life is short, try Golang.
As a code farmer who once heavily used Delphi, it is hard to understand why it has been advertised as a so-called database development. Even if mobile game development started two years ago, it has never been available, or support the available frameworks provided by its fans (think about Cocos2d ). It is estimated that it will not catch up with this tide. It is too important to take advantage of the current situation.
Although it has long been able to develop applications on multiple platforms, I am afraid it only positions itself as a so-called APP development tool, which is average and ordinary.
Even in some ways, it is really convenient and even a powerful tool.
Life is short