İos_base :: sync_with_stdio (false) 'un önemi; cin.tie (NULL);


146

Dahil etmenin önemi nedir

ios_base::sync_with_stdio(false);
cin.tie(NULL);

C ++ programlarında

Testlerimde, yürütme süresini hızlandırıyor, ancak bunu ekleyerek endişelenmem gereken bir test durumu var mı?

2 ifadenin her zaman birlikte olması gerekir mi yoksa ilki yeterli cin.tie(NULL)midir , yani yok sayılıyor mu?

Ayrıca, değeri olarak ayarlanmışsa eşzamanlı C ve C ++ komutlarının kullanılmasına izin verilebilir falsemi?

https://www.codechef.com/viewsolution/7316085

Yukarıdaki kod scanf/printf, değeri olarak bir C ++ programında kullanılana kadar, iyi çalıştı true. Bu durumda, bir segmentasyon hatası verdi. Bunun olası açıklaması ne olabilir?


Aslında yanlış kullandın. Kodunuz öyle diyor ???
Suraj Jain

Yanıtlar:


231

İki çağrının performansla hiçbir ilgisi olmayan farklı anlamları vardır; Aslında bu yürütme zamanı hızlandırır (veya olabilir sadece bir yan etkisi). Her birinin ne yaptığını anlamalı ve her programa körü körüne dahil etmemelisiniz çünkü bir optimizasyona benziyorlar.

ios_base::sync_with_stdio(false);

Bu, C ve C ++ standart akışları arasındaki senkronizasyonu devre dışı bırakır. Varsayılan olarak, tüm standart akışlar senkronize edilir, bu da pratikte C ve C ++ tarzı G / Ç'yi karıştırmanıza ve makul ve beklenen sonuçlar almanıza olanak tanır. Senkronizasyonu devre dışı bırakırsanız, C ++ akışlarının kendi bağımsız tamponlarına sahip olmasına izin verilir, bu da C ve C ++ tarzı G / Ç'yi bir macera haline getirir.

Ayrıca, senkronize edilmiş C ++ akışlarının iş parçacığı açısından güvenli olduğunu unutmayın (farklı iş parçacıklarından çıktılar araya girebilir, ancak veri yarışları alamazsınız).

cin.tie(NULL);

Bu cin,cout . Bağlı akışlar, diğer akıştaki her bir G / Ç işleminden önce bir akışın otomatik olarak temizlenmesini sağlar.

Varsayılan olarak cin, coutduyarlı bir kullanıcı etkileşimi sağlamak için bağlanmıştır . Örneğin:

std::cout << "Enter name:";
std::cin >> name;

Eğer cinve coutbağlı, sen çıkış kullanıcıdan programı istemleri girişinden önce (konsolda yani görünür) temizlenip bekleyebilirsiniz. Akışları çözerseniz, program kullanıcının adını girmesini beklemeyi engelleyebilir ancak "Ad girin" mesajı henüz görünmez (çünkücout varsayılan olarak arabelleğe alınmış , çıktı konsolda yalnızca istek üzerine veya arabellek dolu).

Yani çöz eğer cindan cout, sifonu emin olmalısınız coutüzerinde girişini beklemeden önce el ekran şey istediğiniz her zamancin .

Sonuç olarak, her birinin ne yaptığını bilin, sonuçlarını anlayın ve daha sonra hız gelişiminin olası yan etkisine gerçekten ihtiyacınız olup olmadığına karar verin .


"Cin girdisini beklemeden önce her şeyi görüntülemek istediğinizde cout'u manuel olarak temizlediğinizden emin olmalısınız" dediğinizde, "... << std :: flush" veya "... < <std :: endl "ile başlayan her satırın sonuna" std :: cout << ... ", değil mi?
Alan

4
Evet, bu kadar basit, ama "her satırın sonu" kısmına dikkat edin. coutbir nedenden dolayı arabelleğe alınır, çok sık yıkarsanız, gerçekten ihtiyacınız olmadığında bir performans isabeti görebilirsiniz.
Ionut

@Ionut, scanf, printf için C'deki tie () işlevine eşdeğer bir şey var mı?
iajnr

1
@iajnr Hayır, doğrudan değil. C'de, daha önce manuel olarak yıkayabilirscanf() , arabelleğe almayı tamamen devre dışı bırakabilir veya satır arabelleğe almaya geçebilirsiniz (satır sonundan sonra veya giriş okunduğunda temizlenmelidirstdin - bkz. Linux.die.net/man/3/setlinebuf ).
Ionut

1
Leetcode'da çalışma zamanını önemli ölçüde iyileştirir, belki de bu rekabetçi web siteleri giriş testleri için özel bir şey yapar.
P0W

18

Bu, C ve C ++ dünyasından GÇ'leri senkronize etmektir. Senkronize ederseniz, tüm ES'lerin siparişlerinin tam olarak beklediğiniz gibi olduğunu garanti edersiniz. Genel olarak, sorun, soruna neden olan ES'lerin arabelleğe alınmasıdır, senkronizasyon her iki dünyanın da aynı tamponları paylaşmasına izin verir. Örneğin cout << "Hello"; printf("World"); cout << "Ciao";; Eğer alırsınız eğer senkronizasyon olmadan sana mecburum bilemezsin HelloCiaoWorldya HelloWorldCiaoya WorldHelloCiao...

tieC ++ dünyasındaki IO kanallarının birbirine bağlı olduğu garantisine sahip olmanızı sağlar , bu da örneğin girdilerin oluşmadan önce her çıktının yıkandığı anlamına gelir (düşünün cout << "What's your name ?"; cin >> name;).

Her zaman C veya C ++ IO'ları karıştırabilirsiniz, ancak makul bir davranış istiyorsanız her iki dünyayı da senkronize etmeniz gerekir. Genel olarak bunları karıştırmanın tavsiye edilmediğine dikkat edin, C'de programlıyorsanız C stdio kullanın ve C ++ programlıysanız akışları kullanın. Ancak mevcut C kitaplıklarını C ++ koduna karıştırmak isteyebilirsiniz ve bu durumda her ikisini de senkronize etmeniz gerekir.


4
Senkronizasyon yapılmasa bile, cout <<siparişi değiştirememek için yapılan farklı çağrılar CiaoHelloWorldörnek durumunuz için mümkün değildir. Senkronizasyon kesinlikle farklı tamponlama yöntemleri ile ilgilidir.
Mikko Rantalainen

3

Kullanmak ve akışları ios_base::sync_with_stdio(false);ayırmak için yeterlidir . Bunun bir tartışmasını Standart C ++ IOStreams ve Locales'te bulabilirsinizCC++ Langer ve Kreft tarafından hazırlanan . Bunun nasıl çalıştığını uygulama tanımlı olarak belirtiyorlar.

cin.tie(NULL)Arama bir üzerinde faaliyetleri arasındaki ayırımı talebinde gibi görünüyor cinve cout. Bunu diğer optimizasyon ile kullanmanın neden bir çökmeye neden olması gerektiğini açıklayamıyorum. Belirtildiği gibi, sağladığınız bağlantı kötü, bu yüzden burada spekülasyon yok.


0

Cin yapmak için sadece yaygın şeyler girişinin daha hızlı çalışmasını .

Hızlı bir açıklama için: ilk satır cin akışı ve C stili stdio araçları (scanf veya gets gibi) arasındaki arabellek senkronizasyonunu kapatır - böylece cin daha hızlı çalışır, ancak stdio araçlarıyla aynı anda kullanamazsınız .

İkinci satır bağları çözer cin den cout - varsayılan olarak cout tampon size bir şey okumak her zaman temizler cin . Ve tekrar tekrar küçük bir şey okuduktan sonra birçok kez küçük bir şey yazdığınızda yavaş olabilir. (Kelimenin tam anlamıyla bağlayarak bu senkronizasyon kapalı hat dönüşler Yani cin için boş yerine cout ).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.