ජාවා හි නිවැරදි ක්ෂුද්ර මිණුම් ලකුණක් ඔබ ලියන්නේ කෙසේද?
මම සිතිය යුතු විවිධ දේ නිදර්ශනය කරන කේත සාම්පල සහ අදහස් කිහිපයක් සොයමි.
උදාහරණය: මිණුම් ලකුණ කාලය / පුනරාවර්තනය හෝ පුනරාවර්තනය / වේලාව මැනිය යුතුද? ඒ ඇයි?
ජාවා හි නිවැරදි ක්ෂුද්ර මිණුම් ලකුණක් ඔබ ලියන්නේ කෙසේද?
මම සිතිය යුතු විවිධ දේ නිදර්ශනය කරන කේත සාම්පල සහ අදහස් කිහිපයක් සොයමි.
උදාහරණය: මිණුම් ලකුණ කාලය / පුනරාවර්තනය හෝ පුනරාවර්තනය / වේලාව මැනිය යුතුද? ඒ ඇයි?
Answers:
ජාවා හොට්ස්පොට් හි නිර්මාතෘවරුන්ගෙන් ක්ෂුද්ර මිණුම් සලකුණු ලිවීම පිළිබඳ උපදෙස් :
රීතිය 0: ජේවීඑම් සහ ක්ෂුද්ර මිණුම් සලකුණු පිළිබඳ පිළිගත් පත්රිකාවක් කියවන්න. හොඳ එකක් තමයි බ්රයන් ගොට්ස්, 2005 . ක්ෂුද්ර මිණුම් සලකුණු වලින් ඕනෑවට වඩා බලාපොරොත්තු නොවන්න; ඒවා මනිනු ලබන්නේ සීමිත පරාසයක ජේවීඑම් කාර්ය සාධන ලක්ෂණ පමණි.
රීති 1: සෑම විටම ඔබගේ පරීක්ෂණ කර්නලය ක්රියාත්මක වන උණුසුම් කිරීමේ අවධියක් ඇතුළත් කරන්න, කාල අදියර (න්) ට පෙර සියලු ආරම්භක සහ සම්පාදනයන් අවුලුවාලීමට එය ප්රමාණවත් වේ. (උණුසුම් කිරීමේ අදියරේදී පුනරාවර්තන අඩුයි. මාපට ඇඟිල්ලේ රීතිය අභ්යන්තර ලූප පුනරාවර්තන දස දහස් ගණනකි.)
රීති 2: සෑම විටම , ආදිය සමඟ ධාවනය කරන්න -XX:+PrintCompilation
, -verbose:gc
එවිට ඔබේ කාල අවධියේදී සම්පාදකයා සහ ජේවීඑම් හි අනෙකුත් කොටස් අනපේක්ෂිත වැඩ නොකරන බව ඔබට තහවුරු කර ගත හැකිය.
රීති 2.1: වේලාව සහ උණුසුම් කිරීමේ අදියරවල ආරම්භයේ සහ අවසානයේ පණිවුඩ මුද්රණය කරන්න, එවිට කාල අදියර තුළ 2 වන රීතියෙන් ප්රතිදානයක් නොමැති බව ඔබට තහවුරු කර ගත හැකිය.
3 වන රීතිය:-client
සහ -server
, සහ OSR සහ සාමාන්ය සම්පාදනයන් අතර වෙනස ගැන සැලකිලිමත් වන්න . මෙම -XX:+PrintCompilation
ධජය උදාහරණයක් ලෙස,-මූලික නොවන පිවිසුම් ස්ථානය දැක්වීමට දී-ලකුණක් සමග OSR compilations වාර්තා: Trouble$1::run @ 2 (41 bytes)
. ඔබ හොඳම කාර්ය සාධනයෙන් පසුව නම් සේවාදායකයාට සේවාදායකයාට සහ OSR වෙත නිතිපතා කැමති වන්න.
4 වන රීතිය: ආරම්භක බලපෑම් පිළිබඳව සැලකිලිමත් වන්න. ඔබේ කාල අවධියේදී පළමු වරට මුද්රණය නොකරන්න, මුද්රණය පැටවීම සහ පන්ති ආරම්භ කිරීම. ඔබ විශේෂයෙන් පන්ති පැටවීම පරීක්ෂා කරන්නේ නම් මිස (සහ එම අවස්ථාවේ දී පරීක්ෂණ පන්ති පමණක් පටවන්න) මිස, උණුසුම් කිරීමේ අවධියෙන් පිටත (හෝ අවසාන වාර්තා කිරීමේ අදියර) නව පන්ති පැටවීම නොකරන්න. 2 වන රීතිය එවැනි බලපෑම් වලට එරෙහිව ඔබේ පළමු ආරක්ෂක මාර්ගයයි.
5 වන රීතිය: ඩියෝප්ටිමීකරණය සහ නැවත සකස් කිරීමේ බලපෑම් පිළිබඳව සැලකිලිමත් වන්න. කාලානුරූපී අවධියේදී පළමු වරට කිසිදු කේත මාර්ගයක් නොගන්න, මන්ද යත්, සම්පාදකයා විසින් කේතය අවුල් කර නැවත සකස් කළ හැකි බැවිනි. 2 වන රීතිය එවැනි බලපෑම් වලට එරෙහිව ඔබේ පළමු ආරක්ෂක මාර්ගයයි.
6 වන රීතිය: සම්පාදකයාගේ මනස කියවීමට සුදුසු මෙවලම් භාවිතා කරන්න, එය නිපදවන කේතය ගැන පුදුම වීමට බලාපොරොත්තු වන්න. යමක් වේගවත් හෝ මන්දගාමී වන්නේ කුමක් ද යන්න පිළිබඳ න්යායන් සැකසීමට පෙර කේතය ඔබම පරීක්ෂා කරන්න.
7 වන රීතිය: ඔබේ මිනුම්වල ශබ්දය අඩු කරන්න. නිශ්ශබ්ද යන්ත්රයක් මත ඔබේ මිණුම් ලකුණ ධාවනය කර පිටස්තරයින් ඉවතලමින් එය කිහිප වතාවක් ධාවනය කරන්න. -Xbatch
යෙදුම සමඟ සම්පාදකයා අනුක්රමික කිරීමට භාවිතා කරන්න , සහ -XX:CICompilerCount=1
සම්පාදකයා තමාට සමාන්තරව ක්රියාත්මක වීම වැළැක්වීම සඳහා සැකසුම සලකා බලන්න . GC පොදු කාර්ය අවම කිරීම සඳහා ඔබේ උපරිමය උත්සාහ කරන්න, Xmx
(ප්රමාණවත් තරම් විශාල) සමාන Xms
කර UseEpsilonGC
එය තිබේ නම් භාවිතා කරන්න .
8 වන රීතිය: ඔබේ මිණුම් ලකුණ සඳහා පුස්තකාලයක් භාවිතා කරන්න, මන්ද එය වඩාත් කාර්යක්ෂම වන අතර මෙම එකම අරමුණ සඳහා දැනටමත් නිදොස් කර ඇත. වැනි JMH , කැලිපරය හෝ පනත් කෙටුම්පත හා ජාවා සඳහා පාවුල් විශිෂ්ට UCSD මිනුම් දඬු .
System.nanoTime()
බව සහතික නොවන බව සැලකිල්ලට ගත යුතුය System.currentTimeMillis()
. එය සහතික වන්නේ අවම වශයෙන් නිවැරදි බව පමණි. කෙසේ වෙතත් එය සාමාන්යයෙන් සැලකිය යුතු ලෙස නිවැරදි ය.
System.nanoTime()
වෙනුවට යමෙකු භාවිතා කළ යුතු ප්රධාන හේතුව වන්නේ System.currentTimeMillis()
කලින් ඇති දේ ඒකාකාරී ලෙස වැඩි වන බවට සහතික වීමයි. ආපසු ලබා දුන් අගයන් අඩු කිරීමෙන් currentTimeMillis
ආයාචනා දෙකක් ඇත්ත වශයෙන්ම negative ණාත්මක ප්රති results ල ලබා දිය හැකිය, සමහර විට පද්ධතියේ වේලාව සමහර එන්ටීපී ඩීමන් විසින් සකස් කර ඇති නිසා විය හැකිය.
මෙම ප්රශ්නයට පිළිතුරු ලෙස සලකුණු කර ඇති බව මම දනිමි, නමුත් ක්ෂුද්ර මිණුම් සලකුණු ලිවීමට අපට උපකාර වන පුස්තකාල දෙකක් සඳහන් කිරීමට මට අවශ්ය විය
නිබන්ධන ආරම්භ කිරීම
නිබන්ධන ආරම්භ කිරීම
ජාවා මිණුම් සලකුණු සඳහා වැදගත් දේ:
System.gc()
පුනරාවර්තන අතර ඇමතිය නොහැකි අතර, එය පරීක්ෂණ අතර ධාවනය කිරීම හොඳ අදහසකි, එවිට සෑම පරීක්ෂණයකටම වැඩ කිරීමට "පිරිසිදු" මතක අවකාශයක් ලැබෙනු ඇත. (ඔව්, gc()
සහතිකයකට වඩා ඉඟියක් වැඩිය, නමුත් එය බොහෝ දුරට ඉඩ තිබේ මගේ අත්දැකීම් අනුව කුණු එකතු කිරීමට .).NET හි මිණුම් සලකුණු රාමුවක් සැලසුම් කිරීම ගැන මම බ්ලොග්කරණයේ යෙදී සිටිමි. මම තියෙනවා යුවලක් වන මීට පෙර තනතුරු ඔබ යම් අදහස් ලබා ගැනීමට හැකි විය හැකි - ඇත්තෙන්ම, නැති හැම දෙයක්ම සුදුසු වනු ඇත, නමුත් එය යම් විය හැක.
gc
සෑම විටම භාවිතයට නොගත් මතකය නිදහස් කරයි යන හැඟීම ඇති කරයි.
System.gc()
කිරීමට අකමැති නම්, පෙර පරීක්ෂණ වලදී නිර්මාණය කරන ලද වස්තූන් හේතුවෙන් එක් පරීක්ෂණයකදී කසළ එකතු කිරීම අවම කිරීමට ඔබ යෝජනා කරන්නේ කෙසේද? මම ප්රායෝගිකයි.
jmh යනු OpenJDK හි මෑත කාලීන එකතු කිරීමක් වන අතර එය ලියා ඇත්තේ ඔරකල් හි සමහර කාර්ය සාධන ඉංජිනේරුවන් විසිනි. බැලීමට වටිනවා.
Jmh යනු JVM ඉලක්ක කරගත් ජාවා සහ වෙනත් භාෂාවලින් ලියා ඇති නැනෝ / මයික්රෝ / සාර්ව මිණුම් සලකුණු තැනීම, ධාවනය කිරීම සහ විශ්ලේෂණය කිරීම සඳහා ජාවා පටි වේ.
නියැදිය තුළ තැන්පත් කර ඇති ඉතා රසවත් තොරතුරු කොටස් අදහස් දැක්වීම් පරීක්ෂා කරයි.
මෙයද බලන්න:
මිණුම් ලකුණ කාලය / පුනරාවර්තනය හෝ පුනරාවර්තනය / වේලාව මැනිය යුතුද? ඒ ඇයි?
එය ඔබ පරීක්ෂා කිරීමට උත්සාහ කරන දේ මත රඳා පවතී .
ඔබ ප්රමාදය ගැන උනන්දුවක් දක්වන්නේ නම් , කාලය / පුනරාවර්තනය භාවිතා කරන්න සහ ඔබ ප්රතිදානය ගැන උනන්දුවක් දක්වන්නේ නම් , පුනරාවර්තන / වේලාව භාවිතා කරන්න.
ඔබ ඇල්ගොරිතම දෙකක් සංසන්දනය කිරීමට උත්සාහ කරන්නේ නම්, ඇණවුම වෙනස් කරමින්, එක් එක් සඳහා අවම වශයෙන් මිණුම් සලකුණු දෙකක් වත් කරන්න. එනම්:
for(i=1..n)
alg1();
for(i=1..n)
alg2();
for(i=1..n)
alg2();
for(i=1..n)
alg1();
එකම ඇල්ගොරිතමයේ ධාවන කාලය තුළ විවිධ පාස් වල සැලකිය යුතු වෙනස්කම් (සමහර විට 5-10%) මම සොයාගෙන ඇත ..
තවද, n ඉතා විශාල බවට වග බලා ගන්න , එවිට එක් එක් ලූපයේ ධාවන කාලය අවම වශයෙන් තත්පර 10 ක් හෝ ඊට වැඩි වේ. වැඩි වැඩියෙන් පුනරාවර්තනයන්, ඔබේ මිණුම් දණ්ඩේ වේලාවේ වඩා වැදගත් සංඛ්යා සහ දත්ත වඩාත් විශ්වාසදායකය.
මිණුම් සලකුණු කළ කේතයෙන් ගණනය කර ඇති ප්රති results ල ඔබ කෙසේ හෝ භාවිතා කරන බවට වග බලා ගන්න. එසේ නොමැතිනම් ඔබේ කේතය ප්රශස්තිකරණය කළ හැකිය.
ජාවා හි ක්ෂුද්ර මිණුම් සලකුණු ලිවීම සඳහා බොහෝ අන්තරායන් ඇත.
පළමුවැන්න: අහඹු ලෙස වැඩි හෝ අඩු කාලයක් ගතවන සියලු ආකාරයේ සිදුවීම් සමඟ ඔබ ගණනය කළ යුතුය: කසළ එකතු කිරීම, හැඹිලි බලපෑම් (ලිපිගොනු සඳහා මෙහෙයුම් පද්ධතිය සහ මතකය සඳහා CPU), IO ආදිය.
දෙවනුව: ඉතා කෙටි කාල පරාසයන් සඳහා මනින ලද වේලාවන්හි නිරවද්යතාවය ඔබට විශ්වාස කළ නොහැක.
තෙවනුව: ක්රියාත්මක කිරීමේදී JVM ඔබේ කේතය ප්රශස්ත කරයි. එබැවින් එකම JVM- උදාහරණයේ විවිධ ලකුණු වේගවත් හා වේගවත් වනු ඇත.
මගේ නිර්දේශ: ඔබේ මිණුම් ලකුණ තත්පර කිහිපයක් ධාවනය කරන්න, එය මිලි තත්පරයට වඩා වැඩ කරන වේලාවට වඩා විශ්වාසදායකය. ජේවීඑම් උණුසුම් කරන්න (මෙයින් අදහස් කරන්නේ මිනුම් නොකර අවම වශයෙන් එක් වරක් මිණුම් ලකුණ ධාවනය කිරීම, ජේවීඑම් හට ප්රශස්තිකරණයන් ක්රියාත්මක කළ හැකි බවයි). ඔබේ මිණුම් ලකුණ කිහිප වතාවක් ධාවනය කරන්න (සමහර විට 5 වතාවක්) සහ මධ්ය අගය ගන්න. සෑම ක්ෂුද්ර මිණුම් ලකුණක්ම නව ජේවීඑම්-නිදසුනක් තුළ ධාවනය කරන්න (සෑම නව මිණුම් දණ්ඩක් සඳහාම අමතන්න) එසේ නොමැතිනම් ජේවීඑම් හි ප්රශස්තිකරණ බලපෑම් පසුව ධාවනය වන පරීක්ෂණ වලට බලපෑම් කළ හැකිය. උණුසුම් කිරීමේ අදියරේදී ක්රියාත්මක නොවන දේවල් ක්රියාත්මක නොකරන්න (මෙය පන්ති භාරය සහ නැවත සකස් කිරීම අවුලුවන බැවින්).
විවිධ ක්රියාත්මක කිරීම් සංසන්දනය කිරීමේදී ක්ෂුද්ර මිණුම් ලකුණෙහි ප්රති results ල විශ්ලේෂණය කිරීම ද වැදගත් විය හැකි බව සැලකිල්ලට ගත යුතුය. එබැවින් වැදගත්කම පිළිබඳ පරීක්ෂණය කළ යුතුය.
මෙයට හේතුව A
මිණුම් ලකුණෙහි බොහෝ ධාවන කාලය තුළ ක්රියාත්මක කිරීම වේගවත් කිරීමට වඩා වේගවත් විය හැකි බැවිනි B
. නමුත් A
ඉහළ ව්යාප්තියක් ද තිබිය හැක, එබැවින් මනින ලද කාර්යසාධන ප්රතිලාභය A
සමඟ සසඳන විට කිසිදු වැදගත්කමක් නොලැබේB
.
එබැවින් මයික්රෝ මිණුම් දණ්ඩක් නිවැරදිව ලිවීම සහ ධාවනය කිරීම පමණක් නොව එය නිවැරදිව විශ්ලේෂණය කිරීම ද වැදගත් ය.
අනෙක් විශිෂ්ට උපදෙස් වලට එකතු කිරීම සඳහා, මම පහත සඳහන් කරුණු ගැන ද සැලකිලිමත් වෙමි:
සමහර CPU සඳහා (උදා: ටර්බෝබූස්ට් සමඟ ඉන්ටෙල් කෝර් i5 පරාසය), උෂ්ණත්වය (සහ දැනට භාවිතා වන මධ්ය ගණන සහ ඒවායේ උපයෝගීතා ප්රතිශතය) ඔරලෝසු වේගයට බලපායි. CPUs ගතිකව ඔරලෝසු කර ඇති බැවින් මෙය ඔබගේ ප්රති .ල කෙරෙහි බලපායි. උදාහරණයක් ලෙස, ඔබට තනි නූල් යෙදුමක් තිබේ නම්, උපරිම ඔරලෝසු වේගය (ටර්බෝබූස්ට් සමඟ) සියලු හරයන් භාවිතා කරන යෙදුමකට වඩා වැඩිය. එබැවින් සමහර පද්ධතිවල තනි හා බහු-නූල් කාර්ය සාධනය සංසන්දනය කිරීමට මෙය බාධාවක් විය හැකිය. උෂ්ණත්වය සහ වාෂ්පීකරණ ද ටර්බෝ සංඛ්යාතය කොපමණ කාලයක් පවත්වා ගෙන යනවාද යන්න මතක තබා ගන්න.
ඔබට සෘජුවම පාලනය කළ හැකි වඩාත් මූලික වශයෙන් වැදගත් අංගයක් විය හැකිය: ඔබ නිවැරදි දේ මනින බවට වග බලා ගන්න! නිදසුනක් ලෙස, ඔබ System.nanoTime()
යම් කේතයක් මිණුම් සලකුණු කිරීමට භාවිතා කරන්නේ නම්, ඔබ උනන්දුවක් නොදක්වන දේවල් මැනීමෙන් වැළකී සිටීමට අර්ථවත් ස්ථානවල ඇමතුම් පැවරුමට දමන්න. උදාහරණයක් ලෙස, එසේ නොකරන්න:
long startTime = System.nanoTime();
//code here...
System.out.println("Code took "+(System.nanoTime()-startTime)+"nano seconds");
ගැටළුව වන්නේ කේතය අවසන් වූ වහාම ඔබට අවසන් වේලාව නොලැබීමයි. ඒ වෙනුවට, පහත සඳහන් දෑ උත්සාහ කරන්න:
final long endTime, startTime = System.nanoTime();
//code here...
endTime = System.nanoTime();
System.out.println("Code took "+(endTime-startTime)+"nano seconds");
println
මිස වෙනම ශීර්ෂ රේඛාවක් හෝ වෙනත් දෙයක් නොවේ, එම ඇමතුම සඳහා නූල් ආර්ග් තැනීමේ පළමු පියවර System.nanoTime()
ලෙස ඇගයීමට ලක් කළ යුතුය . පළමුවැන්නා සමඟ දෙවැන්න සමඟ කළ නොහැකි කිසිවක් සම්පාදකයෙකුට කළ නොහැකි අතර, නැවතුම් වේලාව සටහන් කිරීමට පෙර අමතර වැඩ කිරීමට කිසිවෙකු උනන්දු නොකරයි.
http://opt.sourceforge.net/ ජාවා මයික්රෝ බෙන්ච්මාර්ක් - විවිධ වේදිකාවල පරිගණක පද්ධතියේ සංසන්දනාත්මක කාර්ය සාධන ලක්ෂණ තීරණය කිරීම සඳහා අවශ්ය වන පාලන කාර්යයන්. ප්රශස්තිකරණ තීරණ මෙහෙයවීමට සහ විවිධ ජාවා ක්රියාත්මක කිරීම් සංසන්දනය කිරීමට භාවිතා කළ හැකිය.