Jako że język Ruby jest moim ulubionym językiem to często lubię śrubować najlepsze wyniki właśnie w nim. Ostatnio zwróciłem uwagę na fakt, że odpalając rozwiązane już zadania, dostaję gorsze rezultaty. Pierwszy przykład z brzegu: http://pl.spoj.com/status/PTEST,radarek/ Zgłoszenia o id 15374614 i 14010695 to dokładnie ten sam kod. Oznacza to, że od kwietnia do dzisiaj musiało się coś zmienić w systemie SPOJ co wpływa negatywnie na wydajność rubiego. Nie wiem jak wygląda dokładnie sposób w jaki odpalacie programy, nie wiem także nic o instalacji rubiego na waszych serwerach. Jednak nie podejrzewam, żeby degradacji uległ sam interpreter rubiego. Podejrzewam natomiast, że może to być związane z dwoma rzeczami.
Po pierwsze, jeśli używacie takich rozwiązań jak rbenv albo rvm, to odpalając polecenie "ruby" odpalamy tak naprawdę nakładkę w postaci skryptu bashowego:
$ file `which ruby`
/Users/radarek/.rbenv/shims/ruby: a bash script text executable
Ten skrypt zajmuje się dopiero wyborem odpowiedniej wersji i odpaleniem jej z ostatecznej ścieżki, np. takiej:
$ ~/.rbenv/versions/2.1.5/bin/ruby -v
ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-darwin14.0]
I teraz porównajmy czas odpalania tych dwóch programów:
$ time ruby -e "puts 'hello'"
hello
real 0m0.111s
user 0m0.057s
sys 0m0.045s
$ time ~/.rbenv/versions/2.1.5/bin/ruby -e "puts 'hello'"
hello
real 0m0.033s
user 0m0.025s
sys 0m0.006s
Czyli już widać pierwszą różnicę rzędu 0.08s. Na tym jednak nie koniec. Ruby domyślnie ładuje tzw. rubygems, które pozwalają na użycie bibliotek w postaci gemów. To niestety też dodaje trochę czasu. Im więcej zainstalowanych jest gemów w systemie, tym większy narzut. Oznacza to, że z czasem, jeśli np. administrator doinstaluje jakieś gemy, ten narzut będzie rosnąć. Zobaczmy jak duży jest ten narzut:
# włączone rubygems (domyślnie)
$ time ~/.rbenv/versions/2.1.5/bin/ruby -e "puts 'hello'"
hello
real 0m0.033s
user 0m0.025s
sys 0m0.005s
# wyłączone rubygems
$ time ~/.rbenv/versions/2.1.5/bin/ruby --disable=gems -e "puts 'hello'"
hello
real 0m0.011s
user 0m0.006s
sys 0m0.003s
Czyli kolejne 0.022s.
Ładowanie rubygems na serwerach SPOJ nie ma sensu, dlatego, że użytkownik nie ma możliwości ich instalacji, zatem nie może zakładać, że jakiś gem jest dostępny.
Sumarycznie daje to 0.1s, co przy wielu zadaniach jest narzutem ogromnym.
Byłbym wdzięczny gdyby administrator zerknął na ten problem.
tl;dr: zalecałbym (jeśli tak nie jest) odpalanie rubiego bez wrapperów (rbenv, rvm) i z wyłączonymi gemami (--disable=gems).