Python පුනරාවර්තන සීමාව පරීක්ෂා කර වෙනස් කරන්න (උදා. sys.setrecursionlimit)

ව්යාපාරික

Python හි, පුනරාවර්තන ගණනට ඉහළ සීමාවක් ඇත (උපරිම පුනරාවර්තන ගණන). ඇමතුම් විශාල සංඛ්යාවක් සමඟ පුනරාවර්තන ශ්රිතයක් ක්රියාත්මක කිරීම සඳහා, සීමාව වෙනස් කිරීම අවශ්ය වේ. සම්මත පුස්තකාලයේ sys මොඩියුලයේ ඇති කාර්යයන් භාවිතා කරන්න.

ප්‍රත්‍යාවර්තන ගණන ද තොග ප්‍රමාණයෙන් සීමා වේ. සමහර පරිසරයන්හිදී, සම්මත පුස්තකාලයේ සම්පත් මොඩියුලය උපරිම තොග ප්‍රමාණය වෙනස් කිරීමට භාවිතා කළ හැක (එය Ubuntu මත ක්‍රියා කළ නමුත් Windows හෝ mac මත නොවේ).

පහත තොරතුරු මෙහි දක්වා ඇත.

  • වත්මන් පුනරාවර්තන සංඛ්‍යාවේ ඉහළ සීමාව ලබා ගන්න:sys.getrecursionlimit()
  • පුනරාවර්තන ගණනෙහි ඉහළ සීමාව වෙනස් කරන්න:sys.setrecursionlimit()
  • තොගයේ උපරිම ප්‍රමාණය වෙනස් කරන්න:resource.setrlimit()

නියැදි කේතය Ubuntu මත ධාවනය වේ.

වත්මන් පුනරාවර්තන සීමාව ලබා ගන්න: sys.getrecursionlimit()

වත්මන් පුනරාවර්තන සීමාව sys.getrecursionlimit() සමඟ ලබා ගත හැක.

import sys
import resource

print(sys.getrecursionlimit())
# 1000

උදාහරණයේදී, උපරිම පුනරාවර්තන සංඛ්‍යාව 1000 වේ, එය ඔබගේ පරිසරය අනුව වෙනස් විය හැක. අප මෙහි ආයාත කරන සම්පත පසුව භාවිතා කරනු ඇත, නමුත් Windows මත නොවන බව සලකන්න.

උදාහරණයක් ලෙස, අපි පහත සරල පුනරාවර්තන ශ්‍රිතය භාවිතා කරමු. ධන නිඛිලයක් n තර්කයක් ලෙස සඳහන් කරන්නේ නම්, ඇමතුම් ගණන n වාරයක් වේ.

def recu_test(n):
    if n == 1:
        print('Finish')
        return
    recu_test(n - 1)

ඔබ ඉහළ සීමාවට වඩා පුනරාවර්තනය කිරීමට උත්සාහ කරන්නේ නම් දෝෂයක් (RecursionError) මතු වනු ඇත.

recu_test(950)
# Finish

# recu_test(1500)
# RecursionError: maximum recursion depth exceeded in comparison

sys.getrecursionlimit() මගින් ලබා ගන්නා අගය දැඩි ලෙස උපරිම පුනරාවර්තන සංඛ්‍යාව නොවන බව සලකන්න, නමුත් පයිතන් පරිවර්තකයේ උපරිම අට්ටි ගැඹුර, එබැවින් ප්‍රත්‍යාවර්තන සංඛ්‍යාව මෙම අගයට වඩා තරමක් අඩු වුවද, දෝෂයක් (RecursionError) වනු ඇත. මතු කරනු ලැබේ.

පයිතන්
python – Max recursion is not exactly what sys.getrecursionlimit() claims. How come? – Stack Overflow

# recu_test(995)
# RecursionError: maximum recursion depth exceeded while calling a Python object

පුනරාවර්තන සීමාව වෙනස් කරන්න: sys.setrecursionlimit()

පුනරාවර්තන ගණනෙහි ඉහළ සීමාව sys.setrecursionlimit() මගින් වෙනස් කළ හැක. ඉහළ සීමාව තර්කයක් ලෙස දක්වා ඇත.

ගැඹුරු පුනරාවර්තනයක් සිදු කිරීමට ඉඩ සලසයි.

sys.setrecursionlimit(2000)

print(sys.getrecursionlimit())
# 2000

recu_test(1500)
# Finish

නිශ්චිත ඉහළ සීමාව ඉතා කුඩා හෝ විශාල නම්, දෝෂයක් සිදුවනු ඇත. මෙම සීමාව (සීමාවේම ඉහළ සහ පහළ සීමාවන්) පරිසරය අනුව වෙනස් වේ.

සීමාවේ උපරිම අගය වේදිකාව මත රඳා පවතී. ඔබට ගැඹුරු පුනරාවර්තනයක් අවශ්‍ය නම්, ඔබට වේදිකාව මඟින් සහාය දක්වන පරාසය තුළ විශාල අගයක් නියම කළ හැක, නමුත් මෙම අගය ඉතා විශාල නම් බිඳ වැටීමක් ඇති කරන බව මතක තබා ගන්න.
If the new limit is too low at the current recursion depth, a RecursionError exception is raised.
sys.setrecursionlimit() — System-specific parameters and functions — Python 3.10.0 Documentation

sys.setrecursionlimit(4)
print(sys.getrecursionlimit())
# 4

# sys.setrecursionlimit(3)
# RecursionError: cannot set the recursion limit to 3 at the recursion depth 1: the limit is too low

sys.setrecursionlimit(10 ** 9)
print(sys.getrecursionlimit())
# 1000000000

# sys.setrecursionlimit(10 ** 10)
# OverflowError: signed integer is greater than maximum

මීළඟට පැහැදිලි කළ පරිදි, උපරිම පුනරාවර්තන සංඛ්‍යාව තොග ප්‍රමාණයෙන් ද සීමා වේ.

තොගයේ උපරිම ප්‍රමාණය වෙනස් කරන්න: resource.setrlimit()

sys.setrecursionlimit() හි විශාල අගයක් සකසා තිබුණද, පුනරාවර්තන ගණන විශාල නම් එය ක්‍රියාත්මක නොවිය හැක. ඛණ්ඩනය කිරීමේ දෝෂයක් පහත පරිදි සිදු වේ.

sys.setrecursionlimit(10 ** 9)
print(sys.getrecursionlimit())
# 1000000000
recu_test(10 ** 4)
# Finish

# recu_test(10 ** 5)
# Segmentation fault

Python හි, උපරිම අට්ටි ප්‍රමාණය වෙනස් කිරීමට සම්මත පුස්තකාලයේ ඇති සම්පත් මොඩියුලය භාවිතා කළ හැක. කෙසේ වෙතත්, සම්පත් මොඩියුලය Unix-විශේෂිත මොඩියුලයක් වන අතර වින්ඩෝස් මත භාවිතා කළ නොහැක.

Resource.getrlimit() සමඟින්, ඔබට තර්කයේ දක්වා ඇති සම්පතේ සීමාව (මෘදු සීමාව, දෘඩ සීමාව) ටපල් එකක් ලෙස ලබා ගත හැක. මෙහිදී, අපි resource.RLIMIT_STACK සම්පත් ලෙස සඳහන් කරමු, එය වත්මන් ක්‍රියාවලියේ ඇමතුම් තොගයේ උපරිම ප්‍රමාණය නියෝජනය කරයි.

print(resource.getrlimit(resource.RLIMIT_STACK))
# (8388608, -1)

උදාහරණයේ, මෘදු සීමාව 8388608 (8388608 B = 8192 KB = 8 MB) වන අතර දෘඩ සීමාව -1 (අසීමිත) වේ.

ඔබට resource.setrlimit() සමඟින් සම්පතේ සීමාව වෙනස් කළ හැක. මෙහිදී මෘදු සීමාව ද -1 ලෙස සකසා ඇත (සීමා නොමැත). ඔබට අසීමිත සීමාව නියෝජනය කිරීමට නියත සම්පත භාවිතා කළ හැක.RLIM_INFINIT.

අට්ටි ප්‍රමාණය වෙනස් වීමට පෙර ඛණ්ඩනය කිරීමේ දෝෂය හේතුවෙන් සිදු කළ නොහැකි වූ ගැඹුරු පුනරාවර්තනය දැන් සිදු කළ හැක.

resource.setrlimit(resource.RLIMIT_STACK, (-1, -1))

print(resource.getrlimit(resource.RLIMIT_STACK))
# (-1, -1)

recu_test(10 ** 5)
# Finish

මෙහිදී, සරල අත්හදා බැලීමක් සඳහා මෘදු සීමාව -1 (සීමාවක් නැත) ලෙස සකසා ඇත, නමුත් ඇත්ත වශයෙන්ම, එය සුදුසු අගයකට සීමා කිරීම වඩා ආරක්ෂිත වනු ඇත.

ඊට අමතරව, මම මගේ මැක් මතද අසීමිත මෘදු සීමාවක් සැකසීමට උත්සාහ කළ විට, පහත දෝෂය ඇති විය.ValueError: not allowed to raise maximum limit
ස්ක්‍රිප්ට් එක sudo එකෙන් දුවන එක උදව් වුනේ නෑ. එය පද්ධතිය මගින් සීමා කළ හැකිය.

සුපිරි පරිශීලකයෙකුගේ ඵලදායී UID සහිත ක්‍රියාවලියකට සීමාවක් නොමැතිව ඕනෑම සාධාරණ සීමාවක් ඉල්ලා සිටිය හැක.
කෙසේ වෙතත්, පද්ධතිය විසින් පනවන ලද සීමාව ඉක්මවන ඉල්ලීමක් තවමත් ValueError ඇති කරයි.
resource.setrlimit() — Resource usage information — Python 3.10.0 Documentation

වින්ඩෝස් සතුව සම්පත් මොඩියුලයක් නොමැති අතර, පද්ධති සීමාවන් හේතුවෙන් mac හට උපරිම තොග ප්‍රමාණය වෙනස් කිරීමට නොහැකි විය. යම් ක්‍රමයක් මගින් Stack Size එක වැඩි කර ගත හැකි නම්, segmentation දෝෂය නිරාකරණය කිරීමට අපට හැකි විය යුතුය, නමුත් අපට මෙය තහවුරු කිරීමට නොහැකි වී ඇත.