আমি সাধারণত শুনেছি যে উত্পাদন কোডটি অলস আই / ও ব্যবহার করা এড়ানো উচিত। আমার প্রশ্ন, কেন? স্রেফ টোয়িংয়ের বাইরে অলস আই / ও ব্যবহার করা কি কখনও ঠিক হবে? এবং বিকল্পগুলি (উদাহরণস্বরূপ গণক) কী আরও ভাল করে তোলে?
আমি সাধারণত শুনেছি যে উত্পাদন কোডটি অলস আই / ও ব্যবহার করা এড়ানো উচিত। আমার প্রশ্ন, কেন? স্রেফ টোয়িংয়ের বাইরে অলস আই / ও ব্যবহার করা কি কখনও ঠিক হবে? এবং বিকল্পগুলি (উদাহরণস্বরূপ গণক) কী আরও ভাল করে তোলে?
উত্তর:
অলস আইওর সমস্যাটি রয়েছে যে আপনি যে পরিমাণ সম্পদ অর্জন করেছেন তা প্রকাশ করা কিছুটা অনাকাঙ্ক্ষিত, কারণ এটি আপনার প্রোগ্রামের ডেটা কীভাবে ব্যবহার করে - তার "চাহিদা প্যাটার্ন" এর উপর নির্ভর করে। আপনার প্রোগ্রামটি একবার সংস্থানটির শেষ রেফারেন্সটি ফেলে দিলে, জিসি শেষ পর্যন্ত সেই সংস্থানটি চালাবেন এবং ছেড়ে দেবেন।
প্রোগ্রাম করার জন্য অলস স্ট্রিমগুলি খুব সুবিধাজনক স্টাইল This এ কারণেই শেল পাইপগুলি এত মজাদার এবং জনপ্রিয়।
তবে, যদি সংস্থানগুলি সীমাবদ্ধ থাকে (যেমন উচ্চ-কর্মক্ষমতা পরিস্থিতি, বা উত্পাদন পরিবেশগুলি যা মেশিনের সীমাতে স্কেল করার আশা করে) পরিষ্কার করতে জিসির উপর নির্ভর করা অপর্যাপ্ত গ্যারান্টি হতে পারে।
স্কেলাবিলিটি উন্নতির জন্য আপনাকে কখনও কখনও উত্সাহিতভাবে উত্সাহ ছেড়ে দিতে হয়।
সুতরাং অলস আইও এর বিকল্পগুলি কী কী যা বর্ধিত প্রক্রিয়াজাতকরণ (যার ফলে খুব বেশি সংস্থান গ্রহণ করবে) ছাড় দেওয়া উচিত নয়? ওয়েল, 2000 এর দশকের শেষের দিকে ওলেগfoldl
কিসেলিভ দ্বারা প্রবর্তিত এবং যেহেতু বেশ কয়েকটি নেটওয়ার্কিং-ভিত্তিক প্রকল্পগুলি জনপ্রিয় করে তুলেছে , আমাদের ভিত্তিক প্রক্রিয়াজাতকরণ, ওরফে পুনরাবৃত্তি বা গণক রয়েছে ।
অলস প্রবাহ হিসাবে বা একটি বিশাল ব্যাচে ডেটা প্রসেসিংয়ের পরিবর্তে আমরা শেষ অংশটি একবার পড়ার পরে রিসোর্সের গ্যারান্টিযুক্ত চূড়ান্তকরণ সহ বিশিষ্ট-ভিত্তিক কঠোর প্রসেসিংয়ের উপর বিমূর্ততা প্রয়োগ করি। এটি পুনরুক্ত-ভিত্তিক প্রোগ্রামিংয়ের মূলমন্ত্র এবং এটি একটি খুব সুন্দর সংস্থান সীমাবদ্ধতা সরবরাহ করে।
আইট্রেটি-ভিত্তিক আইওর সর্বনিম্ন দিকটি এটির কিছুটা বিশ্রী প্রোগ্রামিং মডেল (মোটামুটি ইভেন্ট-ভিত্তিক প্রোগ্রামিংয়ের সাথে মিলিয়ে দুর্দান্ত থ্রেড-ভিত্তিক নিয়ন্ত্রণ)। এটি অবশ্যই কোনও প্রোগ্রামিং ভাষায় একটি উন্নত প্রযুক্তি। এবং বেশিরভাগ প্রোগ্রামিং সমস্যার জন্য, অলস আইও সম্পূর্ণ সন্তোষজনক। তবে, আপনি যদি অনেকগুলি ফাইল খুলছেন, বা অনেকগুলি সকেটে কথা বলছেন বা অন্যথায় বহু যুগপত সংস্থান ব্যবহার করছেন, তবে একটি পুনরাবৃত্তি (বা গণক) পদ্ধতির অর্থ হতে পারে।
ডনস একটি খুব ভাল উত্তর সরবরাহ করেছে, তবে পুনরাবৃত্তির অন্যতম আকর্ষণীয় বৈশিষ্ট্য (আমার জন্য) তিনি কী রেখে গেছেন: তারা স্পেস ম্যানেজমেন্ট সম্পর্কে তর্ক করা সহজ করে দেয় কারণ পুরাতন ডেটা অবশ্যই স্পষ্টভাবে ধরে রাখতে হবে। বিবেচনা:
average :: [Float] -> Float
average xs = sum xs / length xs
এটি একটি সুপরিচিত স্পেস ফাঁস, কারণ এবং xs
উভয়ই গণনা করার জন্য পুরো তালিকাটি অবশ্যই মেমরিতে ধরে রাখতে হবে । ভাঁজ তৈরি করে দক্ষ ভোক্তা তৈরি করা সম্ভব:sum
length
average2 :: [Float] -> Float
average2 xs = uncurry (/) <$> foldl (\(sumT, n) x -> (sumT+x, n+1)) (0,0) xs
-- N.B. this will build up thunks as written, use a strict pair and foldl'
তবে প্রতিটি স্ট্রিম প্রসেসরের জন্য এটি করতে কিছুটা অসুবিধে হয়। কিছু সাধারণীকরণ রয়েছে ( কনল এলিয়ট - বিউটিফুল ফোল্ড জিপিং ), তবে তারা মনে হয় নি যে এগুলি ধরা পড়ে। যাইহোক, পুনরাবৃত্তিগুলি আপনাকে অনুরূপ স্তরের অভিব্যক্তি পেতে পারে।
aveIter = uncurry (/) <$> I.zip I.sum I.length
এটি কোনও ভাঁজের মতো দক্ষ নয় কারণ তালিকাটি এখনও একাধিকবার পুনরাবৃত্তি করা হয়েছে, তবে এটি খণ্ডে সংগ্রহ করা হয়েছে যাতে পুরানো তথ্য দক্ষতার সাথে আবর্জনা সংগ্রহ করা যায়। এই সম্পত্তিটি ভাঙ্গার জন্য, স্ট্রিম 2 তালিকা সহ পুরো ইনপুটটি স্পষ্টভাবে ধরে রাখা দরকার:
badAveIter = (\xs -> sum xs / length xs) <$> I.stream2list
প্রোগ্রামিং মডেল হিসাবে পুনরাবৃত্তির অবস্থা একটি কাজ চলছে, তবে এটি এক বছর আগের তুলনায় অনেক বেশি ভাল। করছি শেখার কি combinators উপযোগী (যেমন zip
, breakE
, enumWith
) এবং যা ফলে বিল্ট-ইন iteratees এবং combinators ক্রমাগত আরো expressivity প্রদান সঙ্গে, কম তাই হয়।
এটি বলেছিল, ডনস সঠিক যে তারা একটি উন্নত কৌশল; আমি অবশ্যই প্রতিটি আই / ও সমস্যার জন্য তাদের ব্যবহার করব না।
আমি সবসময় প্রোডাকশন কোডে অলস আই / ও ব্যবহার করি। ডোন যেমন উল্লেখ করেছে এটি নির্দিষ্ট পরিস্থিতিতে কেবল একটি সমস্যা। তবে কয়েকটি ফাইল পড়ার জন্য এটি দুর্দান্ত কাজ করে।
আপডেট: সম্প্রতি হ্যাসেল -ক্যাফেতে ওলেগ কিসেলজভ দেখিয়েছেন যে unsafeInterleaveST
(যা এসটি মোনাডের মধ্যে অলস আইও প্রয়োগ করার জন্য ব্যবহৃত হয়) খুব অনিরাপদ - এটি যৌক্তিক যুক্তি ভঙ্গ করে। তিনি দেখায় যে এটা গঠন করা করার অনুমতি দেয় bad_ctx :: ((Bool,Bool) -> Bool) -> Bool
যে এই ধরনের
> bad_ctx (\(x,y) -> x == y)
True
> bad_ctx (\(x,y) -> y == x)
False
==
পরিবর্তিত যদিও ।
অলস আইওর সাথে আর একটি সমস্যা: প্রকৃত আইও অপারেশনটি অনেক দেরি না হওয়া পর্যন্ত পিছিয়ে যেতে পারে, উদাহরণস্বরূপ ফাইলটি বন্ধ হওয়ার পরে is হাস্কেল উইকির উদ্ধৃতি - অলস আইও নিয়ে সমস্যা :
উদাহরণস্বরূপ, একটি সাধারণ শিক্ষামূলক ভুলটি কোনও ফাইল পড়া শেষ করার আগে বন্ধ করে দেওয়া:
wrong = do fileData <- withFile "test.txt" ReadMode hGetContents putStr fileData
ফাইলটি ডেটা বাধ্য করার আগে ফাইলটি হ্যান্ডেলটি বন্ধ করে দেয় সমস্যাটি রয়েছে। সঠিক পদ্ধতিটি ফাইলের সাথে সমস্ত কোডটি পাস করা:
right = withFile "test.txt" ReadMode $ \handle -> do fileData <- hGetContents handle putStr fileData
এখানে, ফাইল শেষ হওয়ার আগে ডেটা গ্রাস করা হয়।
এটি প্রায়শই অপ্রত্যাশিত এবং সহজেই তৈরি করা ত্রুটি।
আরও দেখুন: অলস I / O সমস্যাগুলির তিনটি উদাহরণ ।
hGetContents
এবং withFile
অর্থহীন কারণ প্রাক্তন হ্যান্ডেলটিকে "সিউডো-ক্লোজড" অবস্থায় রাখে এবং আপনার জন্য (অলসভাবে) ক্লোজিং পরিচালনা করবে সুতরাং কোডটি হুবহু সমান readFile
, বা এমনকি openFile
ছাড়াই hClose
। এটা কি অলস ইনপুট / আউটপুট মূলত এর হয় । আপনি যদি ব্যবহার না করেন readFile
, getContents
বা hGetContents
আপনি অলস আই / ও ব্যবহার করছেন না। উদাহরণস্বরূপ line <- withFile "test.txt" ReadMode hGetLine
কাজ করে।
hGetContents
আপনার জন্য ফাইলটি বন্ধ করে দেওয়া পরিচালনা করবে, তবে এটি নিজেকে "তাড়াতাড়ি" বন্ধ করাও জায়েয এবং সংস্থান পূর্বাভাস প্রকাশিত হয়েছে তা নিশ্চিত করতে সহায়তা করে।
অলস আইওর সাথে আর একটি সমস্যা যা এখনও অবধি উল্লেখ করা হয়নি তা হ'ল এটির অবাক করা আচরণ রয়েছে। একটি সাধারণ হাস্কেল প্রোগ্রামে, আপনার প্রোগ্রামের প্রতিটি অংশের মূল্যায়ন যখন করা হয় তখন কখনও কখনও এটি অনুমান করা কঠিন হতে পারে, তবে সৌভাগ্যক্রমে শুদ্ধতার কারণে আপনার কার্য সম্পাদনের সমস্যা না থাকলে এটি আসলেই কিছু যায় আসে না। অলস আইও চালু করা হলে, আপনার কোডের মূল্যায়নের ক্রমটি এর অর্থের উপরে আসলে একটি প্রভাব ফেলে, তাই আপনি যে ক্ষতিহীন হিসাবে ভাবতে অভ্যস্ত হন তা আপনাকে প্রকৃত সমস্যা তৈরি করতে পারে।
উদাহরণস্বরূপ, কোড সম্পর্কে এমন একটি প্রশ্ন যা যুক্তিসঙ্গত বলে মনে হচ্ছে তবে এটি পিছিয়ে আইও দ্বারা আরও বিভ্রান্তিকর করা হয়েছে: ফাইল বনাম ওপেনফাইলে
এই সমস্যাগুলি মারাত্মকভাবে মারাত্মক নয়, তবে এটি নিয়ে চিন্তা করার মতো আরও একটি বিষয়, এবং সমস্ত কাজ এগিয়ে নিয়ে যাওয়ার ক্ষেত্রে যদি সত্যিকারের সমস্যা না হয় তবে আমি ব্যক্তিগতভাবে অলস আইও এড়িয়ে চলি।