দেজউয়ের উত্তরটির সম্প্রসারণ (সম্পাদনা 2):
File.open(filename,'w'){ |f|
uri = URI.parse(url)
Net::HTTP.start(uri.host,uri.port){ |http|
http.request_get(uri.path){ |res|
res.read_body{ |seg|
f << seg
#hack -- adjust to suit:
sleep 0.005
}
}
}
}
কোথায় filename
এবংurl
স্ট্রিং হয়।
sleep
কমান্ড একটি হ্যাক করে যায় নাটকীয়ভাবে CPU ব্যবহার কমাতে যখন নেটওয়ার্ক সীমিত ফ্যাক্টর। নেট :: এইচটিটিপি ফলনের আগে বাফার (v1.9.2 এ 16kB) অপেক্ষা করার অপেক্ষা রাখে না, সুতরাং সিপিইউ ব্যস্ত হয়ে পড়ে ছোট ছোট খণ্ডগুলি moving এক মুহুর্তের জন্য ঘুমানো বাফারকে লেখার মধ্যে পূরণ করার সুযোগ দেয় এবং সিপিইউ ব্যবহারটি আমার প্রয়োগের 4-5x পার্থক্যের সাথে কার্ল সমাধানের সাথে তুলনীয়। আরও শক্তিশালী সমাধান এর অগ্রগতি পরীক্ষা করতে পারেf.pos
লক্ষ্য নির্ধারণের সময়সীমার করতে এবং সময়সীমার সামঞ্জস্য করতে পারে, বলুন, বাফার সাইজের 95% - বাস্তবে আমি উদাহরণটিতে 0.005 নম্বর পেয়েছি।
দুঃখিত, তবে রুফির বাফারটি পূরণের অপেক্ষার আরও মার্জিত উপায় আমি জানি না।
সম্পাদনা:
এটি এমন একটি সংস্করণ যা বাফারকে সামর্থ্য বা ঠিক নীচে রাখতে স্বয়ংক্রিয়ভাবে নিজেকে সামঞ্জস্য করে। এটি একটি অবাস্তব সমাধান, তবে এটি ঠিক তত দ্রুত বলে মনে হচ্ছে, এবং সিপিইউর মতো সময় কম ব্যবহার করা উচিত, কারণ এটি কার্ল করার জন্য ডাকে।
এটি তিনটি পর্যায়ে কাজ করে। ইচ্ছাকৃতভাবে দীর্ঘ ঘুমের সময় সহ একটি সংক্ষিপ্ত শিক্ষার সময়কাল একটি সম্পূর্ণ বাফারের আকারকে প্রতিষ্ঠিত করে। ড্রপ পিরিয়ড প্রতিটি পুনরাবৃত্তির সাথে ঘুমের সময় দ্রুত হ্রাস করে, এটি কোনও বৃহত্তর ফ্যাক্টর দ্বারা গুণ করে, যতক্ষণ না এটি কোনও আন্ডার-ভরা বাফারটি খুঁজে পায়। তারপরে, স্বাভাবিক সময়কালে, এটি একটি ছোট ফ্যাক্টর দ্বারা উপরে এবং নীচে সামঞ্জস্য হয়।
আমার রুবি কিছুটা মরিচা, তাই আমি নিশ্চিত যে এটি আরও উন্নত হতে পারে। প্রথমত, পরিচালনা করার কোনও ত্রুটি নেই। এছাড়াও, সম্ভবত এটি ডাউনলোড থেকে দূরে কোনও বস্তুর মধ্যে পৃথক করা যেতে পারে, যাতে আপনি কেবল নিজের লুপটিতে কল করতে চান autosleep.sleep(f.pos)
? আরও ভাল, নেট :: এইচটিটিপি উত্পাদনের আগে একটি পূর্ণ বাফারের জন্য অপেক্ষা করার জন্য পরিবর্তন করা যেতে পারে:
def http_to_file(filename,url,opt={})
opt = {
:init_pause => 0.1, #start by waiting this long each time
# it's deliberately long so we can see
# what a full buffer looks like
:learn_period => 0.3, #keep the initial pause for at least this many seconds
:drop => 1.5, #fast reducing factor to find roughly optimized pause time
:adjust => 1.05 #during the normal period, adjust up or down by this factor
}.merge(opt)
pause = opt[:init_pause]
learn = 1 + (opt[:learn_period]/pause).to_i
drop_period = true
delta = 0
max_delta = 0
last_pos = 0
File.open(filename,'w'){ |f|
uri = URI.parse(url)
Net::HTTP.start(uri.host,uri.port){ |http|
http.request_get(uri.path){ |res|
res.read_body{ |seg|
f << seg
delta = f.pos - last_pos
last_pos += delta
if delta > max_delta then max_delta = delta end
if learn <= 0 then
learn -= 1
elsif delta == max_delta then
if drop_period then
pause /= opt[:drop_factor]
else
pause /= opt[:adjust]
end
elsif delta < max_delta then
drop_period = false
pause *= opt[:adjust]
end
sleep(pause)
}
}
}
}
end