রুবি টেইল কল অপটিমাইজেশন সম্পাদন করে?


92

কার্যকরী ভাষাগুলি প্রচুর সমস্যা সমাধানের জন্য পুনরাবৃত্তি ব্যবহারের দিকে পরিচালিত করে এবং তাই তাদের মধ্যে অনেকে টেল কল অপটিমাইজেশন (টিসিও) সম্পাদন করে। টিসিও অন্য ফাংশন থেকে কল (বা নিজেই, যার ক্ষেত্রে এই বৈশিষ্ট্যটি টেল রিকার্সন ইলিমিনেশন নামে পরিচিত, এটি টিসিওর একটি উপসেট)) ফাংশনের শেষ ধাপ হিসাবে নতুন স্ট্যাক ফ্রেমের প্রয়োজন হয় না, যা ওভারহেড এবং মেমরির ব্যবহার হ্রাস করে।

রুবি স্পষ্টতই ফাংশনাল ভাষাগুলি (ল্যাম্বডাস, মানচিত্রের মতো ফাংশন ইত্যাদি) থেকে প্রচুর ধারণাগুলি "ধার" পেয়েছেন, যা আমাকে কৌতূহলী করে তোলে: রুবি কি টেল কল অপ্টিমাইজেশন সম্পাদন করে?

উত্তর:


128

না, রুবি টিসিও করেন না। যাইহোক, এটা এছাড়াও নেই না TCO সঞ্চালন।

রুবি ল্যাঙ্গুয়েজ স্পেসিফিকেশন টিসিও সম্পর্কে কিছু বলে না। এটি আপনাকে এটি করতে হবে তা বলে না, তবে এটি এটিও বলে না যে আপনি এটি করতে পারবেন না । আপনি কেবল এটির উপর নির্ভর করতে পারবেন না ।

এটি স্কিমের বিপরীতে, যেখানে ভাষা নির্দিষ্টকরণের প্রয়োজন যে সমস্ত বাস্তবায়ন অবশ্যই টিসিও করবে। তবে এটি পাইথনেরও ভিন্ন নয়, যেখানে একাধিক অনুষ্ঠানে গাইডো ভ্যান রসম খুব স্পষ্ট করে জানিয়েছে (শেষ বার মাত্র কয়েক দিন আগে) পাইথন বাস্তবায়ন টিসিও করা উচিত নয়

ইউকিহিরো মাৎসুমোটো টিসিওর প্রতি সহানুভূতিশীল, তিনি কেবল সমস্ত প্রয়োগকারীকে সমর্থন করতে বাধ্য করতে চান না । দুর্ভাগ্যক্রমে, এর অর্থ হ'ল আপনি টিসিও'র উপর নির্ভর করতে পারবেন না, বা যদি আপনি করেন তবে আপনার কোডটি আর রুবি বাস্তবায়নের জন্য পোর্টেবল হবে না।

সুতরাং, কিছু রুবি বাস্তবায়ন টিসিও সম্পাদন করে তবে বেশিরভাগ তা করেন না। YARV, উদাহরণস্বরূপ, TCO সমর্থন করে, যদিও (মুহুর্তের জন্য) আপনাকে সোর্স কোডের একটি লাইন স্পষ্টতই uncomment করতে হবে এবং VM পুনরায় কম্পাইল করতে হবে, TCO সক্রিয় করতে হবে - ভবিষ্যতের সংস্করণগুলিতে এটি প্রয়োগের প্রমাণিত হওয়ার পরে ডিফল্টরূপে চালু হতে চলেছে স্থিতিশীল তোতা ভার্চুয়াল মেশিন টিসিও স্থানীয়ভাবে সমর্থন করে, তাই কার্ডিনাল খুব সহজেই এটি সমর্থন করতে পারে। সিএলআরটির টিসিওর জন্য কিছু সমর্থন রয়েছে, যার অর্থ আয়রণরবি এবং রুবি.এনইটি সম্ভবত এটি করতে পারে। রুবিনিয়াস সম্ভবত এটিও করতে পারতেন।

তবে জেআরবি এবং এক্সরুবি টিসিও সমর্থন করে না এবং তারা সম্ভবত তা করবে না, যদি না জেভিএম নিজেই টিসিওর পক্ষে সমর্থন না পায়। সমস্যাটি হ'ল: যদি আপনি একটি দ্রুত বাস্তবায়ন করতে চান এবং জাভার সাথে দ্রুত এবং বিরামবিহীন সংহত করতে চান তবে আপনার জাভার সাথে স্ট্যাকের সাথে সামঞ্জস্যপূর্ণ হওয়া উচিত এবং যতটা সম্ভব জেভিএমের স্ট্যাকটি ব্যবহার করা উচিত। আপনি ট্রাম্পোলাইন বা স্পষ্ট ধারাবাহিকতা-পাসিং শৈলীর সাহায্যে টিসিও সহজেই বাস্তবায়ন করতে পারেন, তবে তারপরে আপনি আর জেভিএম স্ট্যাক ব্যবহার করছেন না, যার অর্থ আপনি যতবারই জাভাতে কল করতে চান বা জাভা থেকে রুবিতে কল করতে চান, আপনাকে কোনও ধরণের সঞ্চালন করতে হবে রূপান্তর, যা ধীর। সুতরাং, এক্সরুবি এবং জেরুবি টিসিও এবং ধারাবাহিকতাগুলির (যা মূলত একই সমস্যা রয়েছে) গতি এবং জাভা সংহতকরণের সাথে যেতে বেছে নিয়েছে।

এটি রুবির সমস্ত প্রয়োগের ক্ষেত্রে প্রযোজ্য যা কিছু হোস্ট প্ল্যাটফর্মের সাথে শক্তভাবে সংহত করতে চায় যা টিসিও স্থানীয়ভাবে সমর্থন করে না। উদাহরণস্বরূপ, আমি অনুমান করি ম্যাকরবি একই সমস্যা হতে চলেছে।


4
আমার ভুল হতে পারে (দয়া করে যদি আমাকে আলোকিত করুন) তবে আমি সন্দেহ করি যে টিসিও সত্যই ওও ভাষাগুলিতে কোনও অর্থবোধ করে, যেহেতু লেজ কলটি অবশ্যই কলার স্ট্যাক ফ্রেমটিকে পুনরায় ব্যবহার করতে সক্ষম হবে। যেহেতু দেরীতে বাইন্ডিং থাকার পরে, কোনও বার্তা প্রেরণের মাধ্যমে কোন পদ্ধতিটি আহ্বান করা হবে তা সংকলনের সময় জানা যায়নি, এটি নিশ্চিত করা কঠিন বলে মনে হচ্ছে (সম্ভবত কোনও টাইপ-প্রতিক্রিয়া জেআইটি সহ, বা কোনও বার্তা প্রয়োগকারীকে স্ট্যাক ফ্রেম ব্যবহার করার জন্য জোর করে একই আকারের বা একই বার্তাটির স্ব-প্রেরণে টিসিওকে সীমাবদ্ধ করে…)।
ড্যামিয়েন পোলেট 13

4
এটি একটি দুর্দান্ত প্রতিক্রিয়া। গুগলের মাধ্যমে সেই তথ্য সহজেই পাওয়া যায় না। Yarv এটি সমর্থন করে যে আকর্ষণীয়।
চার্লি ফুলগুলি

15
ড্যামিয়েন, এটি প্রমাণিত হয়েছে যে সত্যিকারের ওও ভাষাগুলির জন্য টিসিওর প্রয়োজনীয়তা রয়েছে : প্রজেক্টফ্রেস্রেস.সুন . com/ প্রকল্পসমূহ / যোগাযোগ / ব্লগ / দেখুন দেখুন । স্ট্যাক ফ্রেম স্টাফ সম্পর্কে খুব বেশি চিন্তা করবেন না: স্ট্যাক ফ্রেমগুলি সংবেদনশীলভাবে ডিজাইন করা পুরোপুরি সম্ভব যাতে তারা টিসিওর সাথে ভালভাবে কাজ করে।
টনি গারনক-জোন্স

4
টনিগ জিএলএস'র রেফারেন্সযুক্ত পোস্টটিকে বিলুপ্তি থেকে রক্ষা করেছেন, এখানে এটি মিরর করে: আশি-www.org.org
ফ্রাঙ্ক শায়ারার

আমি একটি হোমওয়ার্ক অ্যাসাইনমেন্ট করছি যা আমাকে স্বেচ্ছাসেবী গভীরতার নেস্টেড অ্যারেগুলির সেটকে পৃথক করা প্রয়োজন। এটি করার সুস্পষ্ট উপায় হ'ল পুনরাবৃত্তির সাথে এবং অনুরূপ ব্যবহারের ক্ষেত্রে অনলাইনে (যা আমি খুঁজে পেতে পারি) পুনরাবৃত্তি ব্যবহার করুন। আমার বিশেষ সমস্যাটি টিসিও ছাড়াও ফুঁসে উঠার খুব সম্ভাবনা নেই তবে পুনরাবৃত্তির দিকে না গিয়ে আমি সম্পূর্ণ সাধারণ সমাধানটি লিখতে পারি না এই বিষয়টি আমাকে বিরক্ত করে।
আইজাক রবিনোভিচ

42

আপডেট: এখানে রুবিতে টিসিওর দুর্দান্ত ব্যাখ্যা: http://nithinbekal.com/posts/ruby-tco/

আপডেট: আপনি tco_method রত্নটিও পরীক্ষা করতে চাইতে পারেন : http://blog.tdg5.com/introducing-t--co_method-gem/

রুবি এমআরআইতে (1.9, 2.0 এবং 2.1) আপনি টিসিও দিয়ে এতে চালু করতে পারেন:

RubyVM::InstructionSequence.compile_option = {
  :tailcall_optimization => true,
  :trace_instruction => false
}

রুবি ২.০ এ ডিফল্টরূপে টিসিও চালু করার প্রস্তাব ছিল। এটি এর সাথে আসা কিছু সমস্যাগুলিও ব্যাখ্যা করে: টেইল কল অপ্টিমাইজেশন: ডিফল্টরূপে সক্ষম করুন ?.

লিঙ্কটি থেকে সংক্ষিপ্ত অংশ:

সাধারণত, লেজ-পুনরাবৃত্তি অপ্টিমাইজেশানের মধ্যে আরও একটি অপ্টিমাইজেশান কৌশল রয়েছে - "কল" থেকে "লাফানো" অনুবাদ translation আমার মতে, এই অপ্টিমাইজেশন প্রয়োগ করা কঠিন কারণ রুবির বিশ্বে "পুনরাবৃত্তি" স্বীকৃতি দেওয়া কঠিন is

পরবর্তী উদাহরণ। ফ্যাক্ট () পদ্ধতিতে "অন্য" ধারাটিতে প্রার্থনা একটি "টেল কল" নয়।

def fact(n) 
  if n < 2
    1 
 else
   n * fact(n-1) 
 end 
end

আপনি যদি () পদ্ধতির উপর টেল-কল অপ্টিমাইজেশন ব্যবহার করতে চান তবে আপনাকে ফ্যাক্ট () পদ্ধতিটি নিম্নরূপে পরিবর্তন করতে হবে (ধারাবাহিকতা পাস করার শৈলী)।

def fact(n, r) 
  if n < 2 
    r
  else
    fact(n-1, n*r)
  end
end

12

এটি থাকতে পারে তবে এর গ্যারান্টি নেই:

https://bugs.ruby-lang.org/issues/1256


লিঙ্কটি এখন পর্যন্ত মারা গেছে।
কারাতেডোগ

@ কারাতেডোগ: ধন্যবাদ, আপডেট হয়েছে। যদিও সত্যি কথা বলতে গেলে সম্ভবত রেফারেন্সটি পুরানো।
স্টিভ জেসোপ

হ্যাঁ :-) আমি কেবল বিষয়টি পড়েছি এবং আমি দেখেছি যে রুবি ২.০ এ এটি সোর্স কোড থেকে সক্ষম করতে পারে (কোনও সি উত্স পরিবর্তন এবং পুনরায় সংযোগ করা যাবে না)।
কারাতেডোগ


2

এটি জর্গ এবং আর্নেস্টের উত্তরের উপর ভিত্তি করে। মূলত এটি বাস্তবায়নের উপর নির্ভর করে।

এমআরআই-তে কাজ করার জন্য আমি আর্নেস্টের উত্তর পেতে পারি না, তবে তা সম্ভব। আমি এই উদাহরণটি পেয়েছি যা এমআরআই 1.9 থেকে 2.1 এর জন্য কাজ করে। এটি একটি খুব বড় সংখ্যা মুদ্রণ করা উচিত। আপনি যদি টিসিও বিকল্পটি সত্যে সেট না করেন, আপনার "স্ট্যাক খুব গভীর" ত্রুটি পাওয়া উচিত।

source = <<-SOURCE
def fact n, acc = 1
  if n.zero?
    acc
  else
    fact n - 1, acc * n
  end
end

fact 10000
SOURCE

i_seq = RubyVM::InstructionSequence.new source, nil, nil, nil,
  tailcall_optimization: true, trace_instruction: false

#puts i_seq.disasm

begin
  value = i_seq.eval

  p value
rescue SystemStackError => e
  p e
end
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.