2012-08-22 11 views
5
#define getcx getchar_unlocked 
inline void inp(int &n)//fast input function 
{ 
    n=0; 
    int ch=getcx();int sign=1; 
    while(ch < '0' || ch > '9'){if(ch=='-')sign=-1; ch=getcx();} 

    while( ch >= '0' && ch <= '9') 
      n = (n<<3)+(n<<1) + ch-'0', ch=getcx(); 
    n=n*sign; 
} 

Witam Używam powyższej funkcji do wprowadzania różnych konkursów kodowania, ale nigdy nie byłem w stanie zrozumieć, dlaczego jest ona szybka. Znam tę logikę, ale nie znam pojęcia jej trwałości. Na przykład, co to jest ta linia robi "#define getcx getchar_unlocked". Także ja nie znam żadnego szybki funkcję wyjścia więc jest jakaś szybka funkcja wyjścia równieżFunkcja szybkiego wprowadzania danych:

+0

Oto kolejne pytanie dotyczące tego tematu: http://stackoverflow.com/questions/9052757/getchar-unlocked-vs-scanf-vs-cin –

+0

Ponieważ nazwa funkcji sugeruje, że nie jest bezpieczna dla wątków, bezpieczna dla wątków funkcja wejściowa wykorzystująca mechanizm synchronizacji może mieć znaczny narzut wydajności w porównaniu z tym. –

+0

Sądząc po okropnym, icky formatowaniu kodu, domyślam się, że pisanie było szybsze niż poprawnie napisana funkcja ... dlatego jest "szybka". – Lundin

Odpowiedz

3

#define używa preprocesor aby getcx być krótki używana dla funkcji getchar_unlocked(), który jest non-funkcja blokowania charakter czytania .

To trochę niesamowite, że już udział w kilku konkursach kodujących bez zrozumienia tego dość prosty kawałek C

Instrukcja stronę I połączone powyżej wspomina putc_unlocked() który brzmi jak prawie to samo, ale na wyjściu .

3

getchar_unlocked() jest wątek niebezpieczny wersję getchar() tego powodu, że getchar_unlocked()wydaje szybciej jest to, że nie sprawdza żadnych blokad w strumieniu wejściowym, skąd ma pobrać znak. Jeśli więc inny wątek zablokował strumień wejściowy, ten wątek to supposed to wait till lock count has come to zero. Ale ta funkcja nie dba o to, niszcząc w ten sposób synchronizację między wątkami.

Ale jeśli masz pewność, że brak synchronizacji nie przyniesie Ci szkody, funkcja ta może pomóc Ci być nieco szybszym.

Ponadto, jego advised, że można go używać bezpiecznie tylko wtedy, gdy wątek wywołujący zablokował stdin przy użyciu flockfile() (lub ftrylockfile()).

2

Zdefiniuj makro o nazwie getcx w taki sposób, że podczas czytania nie będą używane żadne zamki. To nie jest wątku bezpieczne, ale szybciej, jeśli nie martwisz się o bezpieczeństwo wątku:

#define getcx getchar_unlocked 

Definiowanie inp jako inline tak, że jest szybsze:

inline void inp(int &n)//fast input function 
{ 
    n=0; 
    int ch=getcx();int sign=1; 
    while(ch < '0' || ch > '9'){if(ch=='-')sign=-1; ch=getcx();} 

Mnożenie n o 10 (z użyciem shift obliczyć 8 * n * n + 2, co może być szybciej):

while( ch >= '0' && ch <= '9') 
      n = (n<<3)+(n<<1) + ch-'0', ch=getcx(); 
    n=n*sign; 
} 

można użyć putchar_unlocked mieć szybszy funkcję wyjścia, gdy bezpieczeństwo wątek nie jest problemem.

+3

"* przy użyciu funkcji przesunięcia do obliczania 8 * n + 2 * n, która jest szybsza *" - która ** może być większa ** lub może być wolniejsza, w zależności od kompilatora, procesora, optymalizacji i wielu innych czynników. –