इसके लिए पाइथोनिक तरीका है:
x = [None] * numElements
या जो भी डिफ़ॉल्ट मान आप के साथ प्रस्तुत करना चाहते हैं, जैसे
bottles = [Beer()] * 99
sea = [Fish()] * many
vegetarianPizzas = [None] * peopleOrderingPizzaNotQuiche
[संपादित करें: कैविट एम्प्टर एक [Beer()] * 99
वाक्य रचना बनाता है Beer
और फिर एक एकल उदाहरण के लिए ९९ संदर्भों के साथ एक सरणी को पॉप्युलेट करता है]
जब आप तत्वों की संख्या बढ़ाते हैं तो पायथन का डिफ़ॉल्ट दृष्टिकोण काफी कुशल हो सकता है।
तुलना
import time
class Timer(object):
def __enter__(self):
self.start = time.time()
return self
def __exit__(self, *args):
end = time.time()
secs = end - self.start
msecs = secs * 1000 # millisecs
print('%fms' % msecs)
Elements = 100000
Iterations = 144
print('Elements: %d, Iterations: %d' % (Elements, Iterations))
def doAppend():
result = []
i = 0
while i < Elements:
result.append(i)
i += 1
def doAllocate():
result = [None] * Elements
i = 0
while i < Elements:
result[i] = i
i += 1
def doGenerator():
return list(i for i in range(Elements))
def test(name, fn):
print("%s: " % name, end="")
with Timer() as t:
x = 0
while x < Iterations:
fn()
x += 1
test('doAppend', doAppend)
test('doAllocate', doAllocate)
test('doGenerator', doGenerator)
साथ में
#include <vector>
typedef std::vector<unsigned int> Vec;
static const unsigned int Elements = 100000;
static const unsigned int Iterations = 144;
void doAppend()
{
Vec v;
for (unsigned int i = 0; i < Elements; ++i) {
v.push_back(i);
}
}
void doReserve()
{
Vec v;
v.reserve(Elements);
for (unsigned int i = 0; i < Elements; ++i) {
v.push_back(i);
}
}
void doAllocate()
{
Vec v;
v.resize(Elements);
for (unsigned int i = 0; i < Elements; ++i) {
v[i] = i;
}
}
#include <iostream>
#include <chrono>
using namespace std;
void test(const char* name, void(*fn)(void))
{
cout << name << ": ";
auto start = chrono::high_resolution_clock::now();
for (unsigned int i = 0; i < Iterations; ++i) {
fn();
}
auto end = chrono::high_resolution_clock::now();
auto elapsed = end - start;
cout << chrono::duration<double, milli>(elapsed).count() << "ms\n";
}
int main()
{
cout << "Elements: " << Elements << ", Iterations: " << Iterations << '\n';
test("doAppend", doAppend);
test("doReserve", doReserve);
test("doAllocate", doAllocate);
}
मेरे विंडोज 7 i7 पर, 64-बिट पायथन देता है
Elements: 100000, Iterations: 144
doAppend: 3587.204933ms
doAllocate: 2701.154947ms
doGenerator: 1721.098185ms
जबकि C ++ देता है (MSVC के साथ निर्मित, 64-बिट, ऑप्टिमाइज़ेशन सक्षम)
Elements: 100000, Iterations: 144
doAppend: 74.0042ms
doReserve: 27.0015ms
doAllocate: 5.0003ms
सी ++ डिबग बिल्ड का निर्माण करता है:
Elements: 100000, Iterations: 144
doAppend: 2166.12ms
doReserve: 2082.12ms
doAllocate: 273.016ms
यहाँ मुद्दा यह है कि पायथन के साथ आप 7-8% प्रदर्शन में सुधार कर सकते हैं, और यदि आपको लगता है कि आप एक उच्च-प्रदर्शन ऐप लिख रहे हैं (या यदि आप कोई ऐसी चीज़ लिख रहे हैं जो वेब सेवा या कुछ और में उपयोग की जाती है) इसे सूँघा नहीं जाना चाहिए, लेकिन आपको अपनी पसंद की भाषा पर पुनर्विचार करने की आवश्यकता हो सकती है।
इसके अलावा, यहाँ पायथन कोड वास्तव में पायथन कोड नहीं है। वास्तव में पाइथोन्सके कोड को यहां स्विच करना बेहतर प्रदर्शन देता है:
import time
class Timer(object):
def __enter__(self):
self.start = time.time()
return self
def __exit__(self, *args):
end = time.time()
secs = end - self.start
msecs = secs * 1000 # millisecs
print('%fms' % msecs)
Elements = 100000
Iterations = 144
print('Elements: %d, Iterations: %d' % (Elements, Iterations))
def doAppend():
for x in range(Iterations):
result = []
for i in range(Elements):
result.append(i)
def doAllocate():
for x in range(Iterations):
result = [None] * Elements
for i in range(Elements):
result[i] = i
def doGenerator():
for x in range(Iterations):
result = list(i for i in range(Elements))
def test(name, fn):
print("%s: " % name, end="")
with Timer() as t:
fn()
test('doAppend', doAppend)
test('doAllocate', doAllocate)
test('doGenerator', doGenerator)
जो देता है
Elements: 100000, Iterations: 144
doAppend: 2153.122902ms
doAllocate: 1346.076965ms
doGenerator: 1614.092112ms
(32-बिट doGenerator doAllocate से बेहतर करता है)।
यहाँ doAppend और doAllocate के बीच का अंतर काफी बड़ा है।
जाहिर है, यहां अंतर केवल तभी लागू होता है जब आप इसे मुट्ठी भर से अधिक बार कर रहे हैं या यदि आप एक भारी लोड सिस्टम पर ऐसा कर रहे हैं, जहां उन संख्याओं को परिमाण के आदेशों से कम किया जा रहा है, या यदि आप काम कर रहे हैं काफी बड़ी सूची।
यहाँ बिंदु: यह सबसे अच्छा प्रदर्शन के लिए pythonic तरीका है।
लेकिन अगर आप सामान्य, उच्च-स्तरीय प्रदर्शन के बारे में चिंता कर रहे हैं, तो पायथन गलत भाषा है। सबसे बुनियादी समस्या यह है कि पायथन फ़ंक्शन कॉल परंपरागत रूप से अन्य भाषाओं की तुलना में 300x धीमी है, जैसे सज्जाकार आदि ( https://wiki.python.org/moin/PythonSpeed/Performtips#Data_Aggregation#Data_Aggregation )।