最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網 會員登陸 & 注冊

Scarpet的奇葩代碼優(yōu)化方法

2019-07-20 23:14 作者:祿存天璣  | 我要投稿

作者:祿存,圖片為堆排序算法,來自網絡,侵刪

前往TIS論壇,享受更好的Markdown渲染體驗 https://forum.tis.world/topic/136/scarpet的奇葩代碼優(yōu)化方法

看過本文并不代表你就不用去把數據結構與算法啃下來了!

字多不看

字多不看,你咋不上天呢

少用return,+=是個好東西,以上

引言

上一篇文章發(fā)布后,我主要做了兩件事:一是寫了個Heap數據結構;第二個就是明確了一下Carpet的腳本語言應該叫Scarpet。再有就是拿著一個測試時候發(fā)現的bug去小小的錘了一下作者,順便學到了點優(yōu)化。

寫出Heap算法以后,發(fā)生了一件奇妙的事情:同樣是一萬次的添加元素并排序,時間復雜度是O(log N)的堆竟然比O(N)慢了不少。后來在經由discord的Kayleigh大佬向gnembon交bug的時候,學到了優(yōu)化方法:把return和if去掉

heap_get(heap_name, index) -> return(element(var(heap_name), index));

heap_get_left_index(index) -> return(index * 2 + 1);

heap_get_right_index(index) -> return(index * 2 + 2);

heap_get_parent_index(index) -> return(if (index == 0, null, floor((index - 1) / 2)));

變成了這樣的代碼

heap_get(heap_name, index) -> element(var(heap_name), index);

heap_get_left_index(index) -> index * 2 + 1;

heap_get_right_index(index) -> index * 2 + 2;

heap_get_parent_index(index) -> if (index == 0, -1, floor((index - 1) / 2));

關于var()的和特殊情況傳引用的方法之后再說。這里只是把return語句去除,讓函數自動返回最后一條語句的輸出——效率真的提高了很多!

猜測

既然“萬物皆函數”,那么有理由相信return()語句的也是函數,而且復雜度不一般。這種反直覺的特性應該還有許多,例如:

  • 自加語句:a += b?和 a = a + b

  • 衛(wèi)語句,例如?https://blog.csdn.net/jw903/article/details/45506777 這個例子

  • if內/外賦值的區(qū)別:a = if (x > y, 'yes', 'no') 和 if (x > y, a = 'yes', a = 'no') 的區(qū)別

  • return 和 if 在加或不加的時的耗時影響

  • 幾種迭代語句,loop, while, for

  • 整數和浮點數的運算

  • 預先聲明變量

  • 變量類型的更改

實驗

針對不同的測試內容設置兩條略微不同的語句,每條語句實驗三次,收集耗時數據

自加自減

/script run a = 0; loop (100000000, a += 1000); - 11s, 10s, 11s

/script run a = 0; loop (100000000, a = a + 1000); - 18s, 19s, 18s


衛(wèi)語句

/script run?

equals(n1, n2) -> (

????if(n1 == n2, return(0));?

????if(n1 < n2, return(-1));?

????return(1)

);?

loop (5000000, equals(floor(rand(2)), floor(rand(2)))); - 43s, 41s, 41s


/script run?

equals(n1, n2) -> (

????if(n1 == n2,?

????????return(0),?

????????if(n1 < n2,?

????????????return(-1),?

????????????return(1)

????????)

????)

);?

loop (5000000, equals(floor(rand(2)), floor(rand(2)))); - 34s, 37s, 37s


賦值在if內和if外

/script run a = ''; loop (100000000, a = if(floor(rand(2)) > 1, 'y', 'n')); - 42s, 43s, 43s

/script run a = ''; loop (100000000, if(floor(rand(2)) > 1, 'a = y', a = 'n')); - 45s, 42s, 42s


return和if

/script run a() -> (return(rand(1000))); loop(1000000, a()); - 5.207s, 5.193s, 5.322s

/script run a() -> (rand(1000));? ? ? ? ?loop(1000000, a()); - 0.153s, 0.137s, 0.146s


/script run a() -> if (rand(2) - 1 > 0, 1, 0); loop (100000000, a()); - 44s, 45s, 42s

/script run a() -> rand(2) - 1 > 0; loop (100000000, a()); - 38s, 39s, 39s


幾種迭代語句

/script run loop (500000000, 0); - 27s, 25s, 26s

/script run while (true, 500000000, 0); - 41s, 43s, 41s

/script run for (range(500000000), 0); - 38s, 39s, 42s


整數與浮點數

/script run global_l1 = l(); global_l2 = l(); loop (1000000, global_l1 += floor(rand(100)); global_l2 += rand(100)); 0;

/script run loop(30, for (global_l1, a = _^_)); - 12s, 15s, 15s

/script run loop(30, for (global_l2, a = _^_)); - 12s, 13s, 13s


預先聲明變量

/script run loop(10000000, a = 0; a = 5; a = sqrt(a)) - 7.037s, 7.154s, 7.776s

/script run loop(10000000, a = 5; a = sqrt(a)) - 4.539s, 5.270s, 5.040s


變量類型更改

/script run loop(20000000, a = l(); a = 10) - 11s, 12s, 12s

/script run loop(20000000, a = l(); b = 10) - 12s, 12s, 12s

數據分析

  • 自加語句:a+=b的速度比 a=a+b快將近一倍

  • 衛(wèi)語句:不用衛(wèi)語句稍微好一點,但是不明顯

  • if內/外賦值:看不出明顯區(qū)別

  • return 和 if :return加了會多花不少時間,if添加前后差別不大

  • 幾種迭代語句:loop最快,while只比for慢一點,后兩者差別不大

  • 整數和浮點數的運算:整數反而慢一些,但是不明顯

  • 預先聲明變量:會花費和正常賦值差不多的時間,

  • 變量類型的更改:看不出明顯區(qū)別

總結

能用a+=b的時候就不要手賤去寫a=a+b;寧愿用麻煩的 if 嵌套也少用用 return?這一大公害;loop是個好東西,整數和浮點數也許不用那么擔心了,沒必要的預先聲明變量就寫在注釋里吧……

如有不滿,歡迎自己測試以后錘作者

Scarpet的奇葩代碼優(yōu)化方法的評論 (共 條)

分享到微博請遵守國家法律
乌兰察布市| 海晏县| 泗阳县| 峨边| 遵义市| 赫章县| 龙里县| 饶平县| 桃江县| 厦门市| 西乌珠穆沁旗| 靖江市| 嘉荫县| 本溪| 凤庆县| 丹江口市| 吉林市| 皮山县| 广元市| 青阳县| 昭苏县| 陆丰市| 陵川县| 奉节县| 乌兰浩特市| 于田县| 读书| 玉山县| 定结县| 芜湖市| 定日县| 镇雄县| 忻州市| 琼海市| 深州市| 始兴县| 策勒县| 榕江县| 靖州| 灌云县| 宜都市|