Modern C performans için ücretsiz alabilirsiniz?
Bazen sadece derleme C 98 kod bile C 11/14 sana bir performans artışı elde edildi. Gerekçe genellikle rvalue kurucular otomatik olarak oluşturulan bazı durumlarda veya STL parçası olarak hareket semantiği çizgisinde. Şimdi bu durumda daha önce aslında zaten rvt li veya benzer derleyici en iyi duruma getirme tarafından işlenen olup olmadığını merak ediyorum.
Benim sorum ise bana, değişiklik olmadan, daha hızlı bir derleyici yeni bir dil özelliklerini destekleyen kullanarak çalışan C 98 kod parçasının gerçek bir örnek verebilirseniz. Anlıyorum bu bir standart uyumlu derleyici değil zorunlu kıldığı kopya elision ve sadece bu nedenle hareket semantiği getireceği konusunda hızlı, ama ben görmek isterim bir daha az patolojik vaka, eğer olacak.
EDİT: Sadece açık olmasını, ben değilim soran olsun yeni Derleyiciler daha hızlıdır eski derleyici, daha ziyade varsa kodu sayede ekleme -std=c 14 benim derleyici bayrakları olurdu daha hızlı koşun (önlemek kopya, ama eğer sen-ebilmek gelmek yukarıya ile başka bir şey dışında hareket semantiği, ben ilgilenir, çok)
CEVAP
C 11 C 03 derleyici yeniden uygulamanın kalitesi hemen hemen ilgisiz performans artışı sınırlandırılmamış neden olabilir 5 Genel kategori farkındayım. Bu hareket anlam çeşitleri vardır.
std::vector
ayrılacak
struct bar{
std::vector<int> data;
};
std::vector<bar> foo(1);
foo.back().data.push_back(3);
foo.reserve(10); // two allocations and a delete occur in C 03
her zaman foo
'nin tampon C bar
9 *Her kopyaladı. 03 yeniden
C 11 bunun yerine, temelde serbest olan bar::data
s, hareket eder.
Bu durumda, bu std
kap vector
içinde en iyi duruma getirme kullanır. C 11 her durumda, aşağıda std
konteynır kullanımı move
verimli anlambilim C nesneleri olduklarından sadece "otomatik olarak" ne zaman, derleyici yükseltme. std
bir kap içeren bloke etme nesneleri de otomatik move
geliştirilmiş kurucular miras.
NRVO hatası
NRVO (dönüş değeri optimizasyon olarak adlandırılır), C 03 kopyalayın düşüyor C 11 başarısız olduğunda geri hareket düşüyor. NRVO başarısızlıkları kolay
std::vector<int> foo(int count){
std::vector<int> v; // oops
if (count<=0) return std::vector<int>();
v.reserve(count);
for(int i=0;i<count; i)
v.push_back(i);
return v;
}
hatta:
std::vector<int> foo(bool which) {
std::vector<int> a, b;
// do work, filling a and b, using the other for calculations
if (which)
return a;
else
return b;
}
Üç değeri dönüş değeri var, ve işlevi içinde iki farklı değerler. Elision işlevi değerleri " dönüş değeri, ama birbirleriyle değil. ile birleşti sağlar İkisi de birbirleri ile birleştirme olmadan dönüş değeri ile birleştirilemez.
Temel sorun NRVO elision kırılgan ve return
site değil yakın değişikliklerle kod aniden hiçbir tanı ile bu noktada büyük bir performans indirimleri yayılan olabilir. En NRVO arıza gibi durumlarda C 11 C 03 kopya ile biter iken move
ile biter.
Bir işlev bağımsız değişkeni dönüyor
Elision da imkansız burada
std::set<int> func(std::set<int> in){
return in;
}
bu ucuz C 11: C 03 kopyayı önlemek için bir yol yoktur. Parametre ve dönüş değeri ömür boyu ve konumu çağıran kod tarafından yönetilen olduğundan, dönüş değeri ile elided, olamaz, işlev için bağımsız değişken.
Ancak, C 11, birinden diğerine hareket edebilir. (Daha az oyuncak bir örnekte, bir şey set
) yapılabilir.
push_back
insert
Konteynerler olmaz içine nihayet elision: ama C 11 aşırı rvalue kopyalarını kaydeder Ekle operatörleri, hareket.
struct whatever {
std::string data;
int count;
whatever( std::string d, int c ):data(d), count(c) {}
};
std::vector<whatever> v;
v.push_back( whatever("some long string goes here", 3) );
C 03 a geçici olarak whatever
oluşturulur, daha sonra vektör v
içine kopyalanır. 2 std::string
tamponlar, aynı veri her ile ayrılır ve atılır.
C 11 whatever
geçici oluşturulur. whatever&&
push_back
aşırı sonra 34* *vektör içine geçici move
ler. std::string
bir arabellek ayrılır ve vektör taşındı. std::string
boş atılır.
Atama
@Jarod42 cevabı aşağıda çalınmış.
Olamaz atama ile ortaya çıkar, ama hareket Elision.
std::set<int> some_function();
std::set<int> some_value;
// code
some_value = some_function();
burada some_function
elide için bir aday döndürür, ama doğrudan bir nesne oluşturmak için kullanılan çünkü, elided olamaz. C 03, yukarıdaki geçici some_value
içine kopyalanan içeriği ile sonuçlanır. C 11, temelde ücretsiz some_value
taşınır.
Yukarıda tam etki için, sizin için hareket yapıcılar ve atama sentezleyip bir derleyici gerekir.
MSVC 2013 std
kaplarda hareket kurucular uygular, ama kendi türlerini devam kurucular sentez değildir.
Türleri std::vector
s ve benzeri içeren MSVC2013, ama MSVC2015 onları almaya başlayacak gibi gelişmeler alamadım.
çınlama ve gcc uzun zamandan beri örtülü hareket kurucular hayata geçirdik. Intel 2013 derleyici -Qoption,cpp,--gen_move_operations
(MSVC2013 ile çapraz uyumlu olması için bir çaba varsayılan olarak yapmazlar) iletirseniz hareket kurucular örtülü nesil destekleyecektir.
Modern Python özel istisnalar bildirme...
DateTime.Şimdi en iyi şekilde ölçmek i...
Ne kadar modern C klasik sıralama algo...
Nasıl sayfa tüm modern tarayıcılarda y...
Ne'en iyi Ücretsiz C Windows için...