Блог пользователя KRISTALL

Автор KRISTALL, 12 лет назад, По-русски

Всем привет. Писать на java недавно начал. Так вот дело в том что есть задача на рекурсию условие можно пасареть по этой ссылке я вроде сделал ее, но проходит из 10 тестов 9 тестов. 1 тест пишет Превышено максимальное время работы вот код http://paste.ideaslabs.com/show/Q6lWOyFdXZ

  • Проголосовать: нравится
  • -21
  • Проголосовать: не нравится

»
12 лет назад, скрыть # |
 
Проголосовать: нравится +11 Проголосовать: не нравится

Писать на java недавно начал.

Уважаемый Йода, Вам скорее всего стоит отказаться от множественного x[i] + " ".

  • »
    »
    12 лет назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится

    Почему?

    • »
      »
      »
      12 лет назад, скрыть # ^ |
       
      Проголосовать: нравится 0 Проголосовать: не нравится

      Каждый раз при этом создается новый экземпляр String. И потом вас радует garbage collector.

      • »
        »
        »
        »
        12 лет назад, скрыть # ^ |
         
        Проголосовать: нравится 0 Проголосовать: не нравится

        Можно на более понятном языке, я же только начинающий...

        • »
          »
          »
          »
          »
          12 лет назад, скрыть # ^ |
           
          Проголосовать: нравится +11 Проголосовать: не нравится

          Особенности Java. Каждый раз при выполнении x[i] + " " создается новая строка, сохранаяется в памяти и затем подается методу println. Эти строки постепенно накапливаются в памяти и тут в дело вступает garbage collector (сборщик мусора).

          На практике получается примерно так: выводится примерно 10^6 чисел, для каждого из них у вас создается новая строка и в итоге у вас 2 мегабайта занято. Через какое-то время, когда памяти станет не хватать, запустится сборщик мусора и удалит ненужные экземпляры, а на это затрачивается время.

          • »
            »
            »
            »
            »
            »
            12 лет назад, скрыть # ^ |
             
            Проголосовать: нравится 0 Проголосовать: не нравится

            И как быть?

            • »
              »
              »
              »
              »
              »
              »
              12 лет назад, скрыть # ^ |
              Rev. 2  
              Проголосовать: нравится +3 Проголосовать: не нравится

              Варианты:

              1. Два вызова print() — один с числом, другой — с пробелом.

              2. Переписать под один длинный StringBuilder. Т.е. по ходу выполнения программы вы не выводите всё сразу на консоль, а сначала складываете в StringBuilder. Этот StringBuilder имеет смысл создать с запасом по памяти изначально. В конце делаете ему ToString() и результат отправляете на консоль.

              • »
                »
                »
                »
                »
                »
                »
                »
                12 лет назад, скрыть # ^ |
                Rev. 2  
                Проголосовать: нравится 0 Проголосовать: не нравится
                1. Кстати, пробовал заслать с двумя вызовами print — не заходит. Маловероятно это причина, но судя по документации println делает за собой flush. Нет, с print('\n') то же самое. Странно. Разве у PrintWriter'а нету буферизации?

                2. А вот через StringBuffer заходит

                • »
                  »
                  »
                  »
                  »
                  »
                  »
                  »
                  »
                  12 лет назад, скрыть # ^ |
                   
                  Проголосовать: нравится 0 Проголосовать: не нравится

                  По умолчанию включен автоматический сброс, который реализован вот так:

                  if (autoFlush && (s.indexOf('\n') >= 0))
                      out.flush();
                  
      • »
        »
        »
        »
        12 лет назад, скрыть # ^ |
        Rev. 3  
        Проголосовать: нравится +3 Проголосовать: не нравится

        Какой тут GC, если программа жрёт меньше 1 мб. Да и создание объектов тут совсем в смешных масштабах. Но в целом проблема с излишним выделеним объектом вполне встречается (несмотря на то, что компилятор может заменить конкатенацию на работу с StringBuilder/StringBuffer). В данном случае педалей добавляет периодический сброс буфера System.out в консоль( или на диск). Если весь вывод хранить в StringBuilder и сбросить его весь целиком в конце, то получите ускорение раз в 8-10 на вашей задаче.