python - programming - তালিকাগুলির উপরে যোগফল(কখনও কখনও) ইটারটোলস.চেইনের চেয়ে দ্রুততর কেন?



python software download (2)

তালিকার একটি তালিকা "সমতল" করতে এটি ব্যবহার করে আমি এখানে বেশ কয়েকটি প্রশ্নের উত্তর দিয়েছি:

>>> l = [[1,2,3],[4,5,6],[7,8,9]]
>>> sum(l,[])

এটি সূক্ষ্ম কাজ করে এবং ফলন দেয়:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

যদিও আমাকে বলা হয়েছিল যে sum অপারেটর a = a + b যা itertools.chain মতো পারফরম্যান্ট নয়

আমার পরিকল্পিত প্রশ্নটি ছিল "তালিকায় এটি কেন স্ট্রিংগুলিতে প্রতিরোধ করা হয় কেন এটি সম্ভব", তবে আমি একই যন্ত্রের সাথে তুলনা করে আমার মেশিনে একটি দ্রুত মাপদণ্ড তৈরি করেছি এবং একই itertools.chain.from_iterable :

import itertools,timeit

print(timeit.timeit("sum(l,[])",setup='l = [[1,2,3],[4,5,6],[7,8,9]]'))
print(timeit.timeit("list(itertools.chain.from_iterable(l))",setup='l = [[1,2,3],[4,5,6],[7,8,9]]'))

আমি এটি বেশ কয়েকবার করেছি এবং আমি সর্বদা নীচের মতো একই পরিসংখ্যান সম্পর্কে জানতে পারি:

0.7155522836070246
0.9883352857722025

আমার অবাক করার জন্য, chain - আমার উত্তরগুলির বিষয়ে বেশ কয়েকটি মন্তব্যে প্রত্যেকের জন্য তালিকার জন্য sum প্রস্তাব - এটি অনেক ধীর।

লুপের for পুনরাবৃত্তি করার সময় এটি এখনও আকর্ষণীয় কারণ এটি আসলে তালিকা তৈরি করে না, তবে তালিকাটি তৈরি করার সময় sum জিততে পারে।

সুতরাং আমরা কি itertools.chain ফেলে itertools.chain প্রত্যাশিত ফলাফলের list হিসাবে sum ব্যবহার করব?

সম্পাদনা: কিছু মন্তব্যের জন্য ধন্যবাদ, আমি তালিকার সংখ্যা বাড়িয়ে আরও একটি পরীক্ষা করেছি

s = 'l = [[4,5,6] for _ in range(20)]'
print(timeit.timeit("sum(l,[])",setup=s))
print(timeit.timeit("list(itertools.chain.from_iterable(l))",setup=s))

এখন আমি বিপরীত পেতে:

6.479897810702537
3.793455760814343

https://src-bin.com


Answer #1

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

বড় তালিকাগুলি সহ, এটি স্পষ্ট হয়ে যায় যে এই ধরণের জিনিসের জন্য sum মোটেই ডিজাইন করা হয়নি:

>>> timeit.timeit('list(itertools.chain.from_iterable(l))',
...               'l = [[i] for i in xrange(5000)]; import itertools',
...               number=1000)
0.20425895931668947
>>> timeit.timeit('sum(l, [])', 'l = [[i] for i in xrange(5000)]', number=1000)
49.55303902059097

Answer #2

প্রথম প্রশ্নের জন্য , "আমার অবাক করে দেওয়ার জন্য, শৃঙ্খলা - আমার উত্তরগুলির বিষয়ে বেশ কয়েকটি মন্তব্যে প্রত্যেকের জন্য তালিকার জন্য অতিরিক্ত পরিমাণে প্রস্তাবিত - অনেক ধীর", আপনার পর্যবেক্ষণের সময়গুলির জন্য দুটি কারণ রয়েছে:

  • ছোট ইনপুটগুলির জন্য, সময়গুলি ফাংশন কল ওভারহেডের দ্বারা প্রাধান্য পায়। list এবং chain.from_iterable উভয়কে কল করা chain.from_iterable কেবল sum কল করার চেয়ে বেশি ব্যয়বহুল। ছোট ইনপুটগুলিকে একত্রিত করার আসল কাজটি ফাংশন এবং পদ্ধতি কল করার কাজের চেয়ে দ্রুত is

  • বড় ইনপুটগুলির জন্য, a = a + b যুক্তির প্রত্যাশিত চতুর্ভুজ আচরণটি প্রাধান্য পাবে।

আপনার অন্য প্রশ্নের জন্য , "কেন স্ট্রিংগুলিতে এটি প্রতিরোধ করা হয় সেই তালিকায় কেন এটি সম্ভব", উত্তরটি হ'ল আমরা সমস্ত চতুষ্কোণ ক্ষেত্রে সনাক্ত করতে এবং তাদের প্রতিবেদন করতে পারি না, সুতরাং কেবলমাত্র একজনকেই হোঁচট খাওয়ার সম্ভাবনা রয়েছে বলে আমরা কেবল রিপোর্ট করি report ঘটনাক্রমে।

এছাড়াও, ''.join(list_of_strings) কাজের ''.join(list_of_strings) যদি আপনি ইতিমধ্যে এটি সম্পর্কে অবগত না হন তবে তা নির্ধারণ করা শক্ত। বিপরীতে, তালিকাগুলির জন্য পারফর্মেন্ট ওয়ার্ক-এর চারপাশগুলি খুঁজে পাওয়া অনেক সহজ, t=[]; for s in list_of_lists: t+=s t=[]; for s in list_of_lists: t+=s

নন-ইটারটুলস বিকল্পটি ব্যবহার করে , আপনার সহজ-ইন-প্লেস তালিকার এক্সটেনশানগুলির সাথে যুক্তিসঙ্গত পারফরম্যান্স পেতে সক্ষম হওয়া উচিত:

result = []
for seq in list_of_lists:
    result += seq

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

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

যাই হোক না কেন , যোগফল () এর মূল কারণটি এটি হ'ল কারণ গুইডো ভ্যান রসুম এবং অ্যালেক্স মার্তেলি ভেবেছিলেন যে ভাষার জন্য সবচেয়ে ভাল:





list