কোন পদ্ধতির এবং একটি পারফরম্যান্স তুলনা কখন ব্যবহার করবেন তার দিকনির্দেশনা সহ পূর্ববর্তী, সহায়ক উত্তরগুলির পরিপূরক করতে ।
পাইপলাইনের বাইরে , ব্যবহার করুন (PSv3 +):
। বস্তু নাম
যেমনটি রাগান্দাক্কের উত্তরে প্রদর্শিত হয়েছে , যা উভয় বাক্যগতভাবেই সহজ এবং আরও দ্রুত ।
একটি পাইপলাইনে যেখানে ফলাফলটি আরও প্রক্রিয়া করা উচিত বা ফলাফল সামগ্রিকভাবে মেমরির সাথে খাপ খায় না, সেখানে ব্যবহার করুন:
$ অবজেক্টস | সিলেক্ট-অবজেক্ট- এক্সপ্যানডপ্রোপার্টি নাম
- স্কট সাদের উত্তরে এর প্রয়োজনীয়তাটি
-ExpandProperty
ব্যাখ্যা করা হয়েছে ।
- আপনি এক-এক-এক প্রক্রিয়াকরণের সাধারণ পাইপলাইন সুবিধাগুলি পান যা সাধারণত আউটপুট উত্পাদন করে এবং মেমরির ব্যবহার স্থির রাখে (যদি না আপনি শেষ পর্যন্ত মেমরির ফলাফল সংগ্রহ করেন) collect
- ট্রেড অফ :
- পাইপলাইন ব্যবহার তুলনামূলকভাবে ধীর ।
জন্য ছোট ইনপুট সংগ্রহ (অ্যারে), আপনি সম্ভবত পার্থক্য লক্ষ্য হবে , এবং, বিশেষ করে কমান্ড লাইন মাঝে মাঝে কমান্ড টাইপ করতে সক্ষম হচ্ছে সহজে আরো গুরুত্বপূর্ণ।
এখানে একটি সহজ-ধরণের বিকল্প রয়েছে , যা তবে ধীরতম পদ্ধতি ; এটি অপারেশন স্টেটমেন্ট নামে পরিচিত সরলীকৃত ForEach-Object
সিনট্যাক্স ব্যবহার করে (আবার, PSv3 +):; উদাহরণস্বরূপ, নিম্নলিখিত PSv3 + সমাধানটি একটি বিদ্যমান কমান্ডে যুক্ত করা সহজ:
$objects | % Name # short for: $objects | ForEach-Object -Process { $_.Name }
সম্পূর্ণতার স্বার্থে জন্য: সামান্য বিখ্যাত PSv4 + + .ForEach()
অ্যারের পদ্ধতি , আরো comprehensivel আলোচনা এই নিবন্ধটি হয় এখনও অন্য বিকল্প :
# By property name (string):
$objects.ForEach('Name')
# By script block (more flexibility; like ForEach-Object)
$objects.ForEach({ $_.Name })
এই পদ্ধতির সদস্য সংখ্যা গণনার অনুরূপ , একই ট্রেডঅফগুলি সহ, পাইপলাইন যুক্তি প্রয়োগ করা হয় নি ; এটি সামান্য ধীর , যদিও পাইপলাইনের তুলনায় লক্ষণীয়ভাবে দ্রুত।
নাম ( স্ট্রিং আর্গুমেন্ট) দ্বারা একক সম্পত্তির মান আহরণের জন্য , এই সমাধানটি সদস্য গণনার সমতুল্য (যদিও পরবর্তীটি সিন্টেক্সটিক্যালি সহজ)।
স্ক্রিপ্ট-ব্লক বৈকল্পিক , নির্বিচারে পারবেন রূপান্তরের ; এটি একটি দ্রুত - সমস্ত-একবারে-মেমরি-একবারে - পাইপলাইন ভিত্তিক ForEach-Object
সেমিডলেট ( %
) এর বিকল্প ।
বিভিন্ন পদ্ধতির কর্মক্ষমতা তুলনা করা
এখানে 10 টির জুড়ে গড়ে ওঠা বিভিন্ন বস্তুর ইনপুট সংগ্রহের ভিত্তিতে বিভিন্ন পদ্ধতির জন্য নমুনার সময় দেওয়া আছে ; নিখুঁত সংখ্যাগুলি গুরুত্বপূর্ণ নয় এবং অনেকগুলি কারণের উপর নির্ভর করে পরিবর্তিত হয় তবে এটি আপনাকে আপেক্ষিক পারফরম্যান্সের ধারণা দেয় (সময়গুলি একক-কোর উইন্ডোজ 10 ভিএম থেকে আসে:10,000
গুরুত্বপূর্ণ
ইনপুট অবজেক্টগুলি নিয়মিত .NET প্রকারের উদাহরণ (যেমন, আউটপুট হিসাবে বাই Get-ChildItem
) বা [pscustomobject]
উদাহরণস্বরূপ (যেমন, আউটপুট হিসাবে ) এর উপর ভিত্তি করে আপেক্ষিক পারফরম্যান্স পরিবর্তিত হয় Convert-FromCsv
।
কারণটি হ'ল [pscustomobject]
সম্পত্তিগুলি গতিশীলভাবে পাওয়ারশেল দ্বারা পরিচালিত হয় এবং এটি নিয়মিত (স্ট্যাটিক্যালি সংজ্ঞায়িত) নিয়মিত। নেট প্রকারের নিয়মিত বৈশিষ্ট্যের চেয়ে আরও দ্রুত এগুলি অ্যাক্সেস করতে পারে। উভয় পরিস্থিতিতে নীচে আচ্ছাদিত করা হয়।
পরীক্ষাগুলি ইতিমধ্যে ইন-মেমরি-ইন-পূর্ণ সংগ্রহগুলি ইনপুট হিসাবে ব্যবহার করে, যাতে খাঁটি সম্পত্তি নিষ্কাশন কর্মক্ষমতাটিতে ফোকাস করতে পারে। ইনপুট হিসাবে স্ট্রিমিং সেমিডলেট / ফাংশন কল সহ, পারফরম্যান্সের পার্থক্যগুলি সাধারণত অনেক কম উচ্চারণিত হয়, কারণ সেই কলটির মধ্যে সময় কাটানো বেশিরভাগ সময় ব্যয় করতে পারে।
বংশবৃদ্ধির %
জন্য , উপনামটি ForEach-Object
সেমিডলেট জন্য ব্যবহৃত হয় ।
নিয়মিত। নেট প্রকার এবং [pscustomobject]
ইনপুট উভয়ের জন্যই সাধারণ সিদ্ধান্তসমূহ প্রযোজ্য :
সদস্য-গণনা ( $collection.Name
) এবং foreach ($obj in $collection)
সমাধানগুলি দ্রুততম পাইপলাইন-ভিত্তিক সমাধানের চেয়ে 10 বা তত বেশি গতির একটি উপাদান দ্বারা দ্রুততম হয় the
আশ্চর্যজনকভাবে, এর থেকে % Name
আরও খারাপ সম্পাদন করে % { $_.Name }
- এই গিটহাব ইস্যুটি দেখুন ।
পাওয়ারশেল কোর এখানে নিয়মিত উইন্ডোজ পাওয়ারশেলকে ছাড়িয়ে যায়।
সঙ্গে সময় নিয়মিত .NET ধরনের :
- পাওয়ারশেল কোর v7.0.0-প্রাকদর্শন 3
Factor Command Secs (10-run avg.)
------ ------- ------------------
1.00 $objects.Name 0.005
1.06 foreach($o in $objects) { $o.Name } 0.005
6.25 $objects.ForEach('Name') 0.028
10.22 $objects.ForEach({ $_.Name }) 0.046
17.52 $objects | % { $_.Name } 0.079
30.97 $objects | Select-Object -ExpandProperty Name 0.140
32.76 $objects | % Name 0.148
- উইন্ডোজ পাওয়ারশেল v5.1.18362.145
Comparing property-value extraction methods with 10000 input objects, averaged over 10 runs...
Factor Command Secs (10-run avg.)
------ ------- ------------------
1.00 $objects.Name 0.012
1.32 foreach($o in $objects) { $o.Name } 0.015
9.07 $objects.ForEach({ $_.Name }) 0.105
10.30 $objects.ForEach('Name') 0.119
12.70 $objects | % { $_.Name } 0.147
27.04 $objects | % Name 0.312
29.70 $objects | Select-Object -ExpandProperty Name 0.343
উপসংহার:
- পাওয়ারশেল কোরে ,
.ForEach('Name')
পরিষ্কারভাবে ছাড়িয়ে যায় .ForEach({ $_.Name })
। উইন্ডোজ পাওয়ারশেলে, কৌতূহলজনকভাবে, আধুনিকগুলি কেবলমাত্র সামান্য হলেও তত দ্রুত।
সঙ্গে সময় [pscustomobject]
দৃষ্টান্ত :
- পাওয়ারশেল কোর v7.0.0-প্রাকদর্শন 3
Factor Command Secs (10-run avg.)
------ ------- ------------------
1.00 $objects.Name 0.006
1.11 foreach($o in $objects) { $o.Name } 0.007
1.52 $objects.ForEach('Name') 0.009
6.11 $objects.ForEach({ $_.Name }) 0.038
9.47 $objects | Select-Object -ExpandProperty Name 0.058
10.29 $objects | % { $_.Name } 0.063
29.77 $objects | % Name 0.184
- উইন্ডোজ পাওয়ারশেল v5.1.18362.145
Factor Command Secs (10-run avg.)
------ ------- ------------------
1.00 $objects.Name 0.008
1.14 foreach($o in $objects) { $o.Name } 0.009
1.76 $objects.ForEach('Name') 0.015
10.36 $objects | Select-Object -ExpandProperty Name 0.085
11.18 $objects.ForEach({ $_.Name }) 0.092
16.79 $objects | % { $_.Name } 0.138
61.14 $objects | % Name 0.503
উপসংহার:
কীভাবে [pscustomobject]
ইনপুট .ForEach('Name')
দিয়ে স্ক্রিপ্ট-ব্লক ভিত্তিক বৈকল্পিককে কার্যকরভাবে চিহ্নিত করে .ForEach({ $_.Name })
।
একইভাবে, [pscustomobject]
ইনপুটটি পাইপলাইন-ভিত্তিক Select-Object -ExpandProperty Name
দ্রুততর করে তোলে , উইন্ডোজ পাওয়ারশেলের কার্যত ভারসাম্যহীন .ForEach({ $_.Name })
, তবে পাওয়ারশেল কোরটিতে এখনও প্রায় 50% ধীর গতি রয়েছে।
সংক্ষেপে বলতে গেলে: এর বিজোড় ব্যতিক্রম সঙ্গে % Name
সঙ্গে [pscustomobject]
বৈশিষ্ট্য উল্লেখ স্ট্রিং ভিত্তিক পদ্ধতি scriptblock ভিত্তিক বেশী সুখ্যাতি।
পরীক্ষার জন্য উত্স কোড :
বিঃদ্রঃ:
$count = 1e4 # max. input object count == 10,000
$runs = 10 # number of runs to average
# Note: Using [pscustomobject] instances rather than instances of
# regular .NET types changes the performance characteristics.
# Set this to $true to test with [pscustomobject] instances below.
$useCustomObjectInput = $false
# Create sample input objects.
if ($useCustomObjectInput) {
# Use [pscustomobject] instances.
$objects = 1..$count | % { [pscustomobject] @{ Name = "$foobar_$_"; Other1 = 1; Other2 = 2; Other3 = 3; Other4 = 4 } }
} else {
# Use instances of a regular .NET type.
# Note: The actual count of files and folders in your home dir. tree
# may be less than $count
$objects = Get-ChildItem -Recurse $HOME | Select-Object -First $count
}
Write-Host "Comparing property-value extraction methods with $($objects.Count) input objects, averaged over $runs runs..."
# An array of script blocks with the various approaches.
$approaches = { $objects | Select-Object -ExpandProperty Name },
{ $objects | % Name },
{ $objects | % { $_.Name } },
{ $objects.ForEach('Name') },
{ $objects.ForEach({ $_.Name }) },
{ $objects.Name },
{ foreach($o in $objects) { $o.Name } }
# Time the approaches and sort them by execution time (fastest first):
Time-Command $approaches -Count $runs | Select Factor, Command, Secs*
$results = @($objects | %{ $_.Name })
। এটি অনেক সময় কমান্ড লাইনে টাইপ করা আরও সুবিধাজনক হতে পারে, যদিও আমি মনে করি স্কটের উত্তর সাধারণত ভাল।