This is a creation in Article, where the information may have evolved or changed. [Original link] (HTTP://WWW.BUGCLOSED.COM/POST/17): Defer in the http://www.bugclosed.com/post/17## defer mechanism go language provides a mechanism to perform operations before functions are returned. In situations where resource recovery is very easy to use (such as file close, Socket link resource, database recall, etc.), resources can be set up where resources are defined, and the code is put together to reduce the likelihood of forgetting to cause a memory leak. Although the defer mechanism is useful, it is not free, the performance will be much worse than the direct function call, secondly, the evaluation of the return value in the defer mechanism is also an error prone place. # # A simple performance comparison test compares performance differences by a defer operation on the lock mechanism. ' Package mainimport ("Sync" "Testing") var (lock = new (sync). Mutex)) func locktest () {lock. Lock () lock. Unlock ()}func lockdefertest () {lock. Lock () defer lock. Unlock ()}func benchmarktest (b *testing. b) {for i: = 0; i < B.N; i++ {locktest ()}}func Benchmarktestdefer (b *testing. B) {for i: = 0; i < B.N; i++ {lockdefertest ()}} "Run command go test-v-test.bench, performance comparison test results are as follows: ' ' BenchmarkTest-8 100000000 1 8.5 ns/opbenchmarktestdefer-8 20000000 56.4 ns/op "from the test results, the defer version of lock operation time consumption is almost 3 times times more than the function direct call. # # Defer execution order and return value evaluation look at a simple test: ' Package Mainimport ("FMT") func test_unnamed () (int) {var i intdefer func () {i++fmt. Println ("Defer A:", I)} () defer func () {i++fmt. Println ("Defer B:", I)} () return I}func test_named () (i int) {defer func () {i++fmt. Println ("Defer c:", I)} () defer func () {i++fmt. PRINTLN ("Defer D:", I)} () return I}func main () {FMT. Println ("Return:", test_unnamed ()) fmt. Println ("Return:", Test_named ())} ' Executes the result: ' ' defer b:1defer a:2return:0defer d:1defer c:2return:2 ' about having multiple defer at the same time Order of execution, which can be seen as the Go compiler maintains an advanced post-out stack for each function. Each time the defer statement is encountered, the execution body is encapsulated and pressed into the stack, and when the function returns, the stack executes sequentially from the stack. So the "defer B" statement is followed by the first call. As to the function evaluation problem, it is possible to understand the execution and evaluation of the TEST_UNNAMED function return and defer as 3 steps: 1. Run to the "return I" statement, the value of the current I value, assigned to the Test_unnamed return value, the return value of the function test 0 (because I is defined in test_unnamed, does not operate, I remain the initial default value). 2. Follow the advanced and out-of-the-way, one call defer statement execution. 3. Execute the true test_unnamed function to return "return". The above is an analysis of the anonymous return value of the case, the named return value test_named the case slightly different, return returned 2, not 0, because the defer function in the return value variable I was modified. This shows that it is extremely easy to have problems with the use of multiple defer and defer functions that also require handling return values, and use caution. # # Defer release lock via defer release lock (sync. Mutex) is a very common scenario, as shown in the following example: "Def getmapdata (key UInt32) Uint32{lock. Lock () defer lock. Unlock () if V, OK: = Mapdata[key]; Ok{return V}return 0} "in such a simple scenario, through the defer directly release the lock, in the subsequent code logic can basically forget the existence of the lock and write code. But there is a lock-granularity problem with this pattern-the entire function is locked. If the LOCK behind a lot of complex or blocking logic (log, access to the database, read data from CH, etc.), will lead to the lock holding time is too large, affecting the processing performance of the system, you can fine-tune the logical function of the split, so that the lock as far as possible only to control the shared resources, discard defer self-control unlock, So as not to spend a lot of lock grain. # # Summary Defer is a very powerful mechanism, particularly in the case of resource release scenarios. It is important to note, however, that defer is not a small performance loss, and that excessive use can cause logic to become complex. 351 reads
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.