মুদ্রণ বিবৃতি সহ টার্মিনালে আউটপুট নিতে কত সময় লাগে তা নিয়ে আমি সর্বদা অবাক / হতাশ হয়ে পড়েছি। সাম্প্রতিক কিছু বেদনাদায়ক ধীর লগিংয়ের পরে আমি এটি খতিয়ে দেখার সিদ্ধান্ত নিয়েছি এবং বেশ অবাক হয়েছি যে প্রায় সমস্ত সময় ব্যয় করে ফলাফলটি প্রক্রিয়া করার জন্য টার্মিনালের জন্য অপেক্ষা করছে।
Stdout লেখার কি কোনওভাবে গতি বাড়ানো যেতে পারে?
আমি print_timer.py
স্ট্রিডাউটে 100k লাইন লেখার সময় টাইমিংয়ের সাথে তুলনা করতে, ফাইলটি লেখার জন্য এবং stdout এ পুনঃনির্দেশিত দিয়ে একটি স্ক্রিপ্ট লিখেছিলাম (' ' এই প্রশ্নের নীচে) /dev/null
। সময় ফলাফল এখানে:
$ python print_timer.py
this is a test
this is a test
<snipped 99997 lines>
this is a test
-----
timing summary (100k lines each)
-----
print :11.950 s
write to file (+ fsync) : 0.122 s
print with stdout = /dev/null : 0.050 s
কি দারুন. পাইথন পর্দার আড়ালে কিছু করছে না তা নিশ্চিত করার জন্য যে আমি স্ট্যাডআউটকে / ডিভ / নাল বা অন্য কিছুতে পুনর্নির্দিষ্ট করেছি, আমি স্ক্রিপ্টের বাইরে পুনর্নির্দেশটি করেছি ...
$ python print_timer.py > /dev/null
-----
timing summary (100k lines each)
-----
print : 0.053 s
write to file (+fsync) : 0.108 s
print with stdout = /dev/null : 0.045 s
সুতরাং এটি একটি অজগর কৌশল নয়, এটি কেবল টার্মিনাল। আমি সর্বদা ডেম্পিং আউটপুট / ডিভ / নাল স্পিডের জিনিসগুলিতে জানতাম, তবে কখনই টের পাইনি যে তা উল্লেখযোগ্য!
টিটিটি কত ধীর গতিতে তা আমাকে অবাক করে দেয়। এটি কীভাবে হতে পারে যে শারীরিক ডিস্কে লেখা "স্ক্রিনে" লেখার চেয়ে সম্ভবত দ্রুত (সম্ভবত একটি অল-র্যাম বিকল্প), এবং কার্যকরভাবে / দেব / নাল দিয়ে আবর্জনায় ফেলে দেওয়ার মতো কার্যকর?
এই লিঙ্কটি কীভাবে টার্মিনালটি I / O- কে অবরুদ্ধ করবে সে সম্পর্কে আলোচনা করে যাতে এটি "ইনপুট] পার্স করতে পারে , এর ফ্রেম বাফারটি আপডেট করতে পারে, উইন্ডোটি স্ক্রোল করার জন্য এক্স সার্ভারের সাথে যোগাযোগ করতে পারে ইত্যাদি" ... তবে আমি করি না সম্পূর্ণরূপে এটি পেতে। এতক্ষণ কী লাগতে পারে?
আমি আশা করি এর বাইরে কোনও উপায় নেই (দ্রুত tty বাস্তবায়নের সংক্ষিপ্ত?) তবে চিত্রটি আমি যেভাবেই জিজ্ঞাসা করব।
আপডেট: কিছু মন্তব্য পড়ার পরে আমি ভাবলাম যে আমার স্ক্রিনের আকারটি মুদ্রণের সময়ে আসলে কতটা প্রভাব ফেলেছে এবং এর কিছুটা তাত্পর্য রয়েছে। উপরের সত্যই ধীর সংখ্যাগুলি আমার জিনোম টার্মিনালটির সাথে 1920x1200 অবধি ফুটিয়েছে। আমি যদি এটি খুব কম করি তবে আমি পাই ...
-----
timing summary (100k lines each)
-----
print : 2.920 s
write to file (+fsync) : 0.121 s
print with stdout = /dev/null : 0.048 s
এটি অবশ্যই ভাল (4x ডলার), তবে আমার প্রশ্ন পরিবর্তন করে না। এটা শুধুমাত্র যোগ করা আমার প্রশ্নের যেমন আমি বুঝতে পারছি না কেন টার্মিনাল পর্দা রেন্ডারিং একটি অ্যাপ্লিকেশন stdout- এ লেখা মন্দীভূত করা উচিত নয়। আমার প্রোগ্রামটি কেন চালিয়ে যাওয়ার জন্য পর্দার রেন্ডারিংয়ের জন্য অপেক্ষা করতে হবে?
সমস্ত টার্মিনাল / টিটি অ্যাপ্লিকেশন কি সমানভাবে তৈরি হয় না? আমার এখনও পরীক্ষা-নিরীক্ষা বাকি আছে। এটি আমার কাছে সত্যই মনে হয় যেমন টার্মিনালটি সমস্ত আগত তথ্য বাফার করতে পারে, অদৃশ্যভাবে এটিকে পার্স / রেন্ডার করতে পারে এবং কেবলমাত্র বর্তমান স্ক্রিন কনফিগারেশনে দৃশ্যমান একটি সাম্প্রতিক ফ্রেমের হারে সাম্প্রতিকতম অংশটি রেন্ডার করতে পারে। সুতরাং আমি যদি ০.০ সেকেন্ডের মধ্যে ডিস্কে + fsync লিখতে পারি তবে একটি টার্মিনাল সেই ক্রমের কিছুতে একই ক্রিয়াকলাপটি সম্পন্ন করতে সক্ষম হবে (এটি করার সময় কয়েকটি স্ক্রিন আপডেট থাকতে পারে)।
আমি এখনও একধরণের আশা করছি এমন একটি টিটিটি সেটিং রয়েছে যা প্রোগ্রামারটির জন্য এই আচরণটি আরও ভাল করার জন্য অ্যাপ্লিকেশন দিক থেকে পরিবর্তন করা যেতে পারে। এটি যদি কঠোরভাবে কোনও টার্মিনাল অ্যাপ্লিকেশন সমস্যা হয় তবে এটি সম্ভবত স্ট্যাকওভারফ্লোতেও অন্তর্ভুক্ত নয়?
আমি কী মিস করছি?
সময় উৎপাদনের জন্য ব্যবহৃত পাইথন প্রোগ্রামটি এখানে:
import time, sys, tty
import os
lineCount = 100000
line = "this is a test"
summary = ""
cmd = "print"
startTime_s = time.time()
for x in range(lineCount):
print line
t = time.time() - startTime_s
summary += "%-30s:%6.3f s\n" % (cmd, t)
#Add a newline to match line outputs above...
line += "\n"
cmd = "write to file (+fsync)"
fp = file("out.txt", "w")
startTime_s = time.time()
for x in range(lineCount):
fp.write(line)
os.fsync(fp.fileno())
t = time.time() - startTime_s
summary += "%-30s:%6.3f s\n" % (cmd, t)
cmd = "print with stdout = /dev/null"
sys.stdout = file(os.devnull, "w")
startTime_s = time.time()
for x in range(lineCount):
fp.write(line)
t = time.time() - startTime_s
summary += "%-30s:%6.3f s\n" % (cmd, t)
print >> sys.stderr, "-----"
print >> sys.stderr, "timing summary (100k lines each)"
print >> sys.stderr, "-----"
print >> sys.stderr, summary