Обычная версия
Java форум JavaTalks
форум программистов

Поиск   Пользователи   Группы   Регистрация 
 Профиль   Личные сообщения 

 Вход 

Сортировка миллиона строк
Список форумов
 ->  Коллекции (Java Collection Framework)


На страницу Пред.  1, 2, 3  След. 
Начать новую тему 
Предыдущая тема :: Следующая тема  
Автор Сообщение
stolzen : 422
Бывалый
Откуда: Нижний Новгород

СообщениеОкт 20, 2011 11:50 
Ответить с цитатой
Jean писал(а):
Вот, если бы исключить эти ребалансировку и все-таки начать измерения вемени со второго раза, результаты были бы вернее.

Возьметесь проверить?


Вы имеете ввиду, что нужно заранее подготовить несбалансированное множество записей, а затем на нем запустить балансировку? Думаю что не выйдет.

В методе addAll происходит проверка, отсортированное ли множество подставляется с помощью (c instanceof SortedSet), и если нет, то вызывается тоже самое - поочередное добавление элементов коллекции с помощью add

Код:
final String[] strings = prepareStrings();

long forSet = timeIt(new Lambda() {
    @Override
    public void apply() {
        new TreeSet<String>(Arrays.asList(strings));
    }
});

System.out.println("time: " + forSet);


Получилось даже больше - time: 2351714714

Код:
final String[] strings = prepareStrings();
final Set<String> set = new TreeSet<String>(Arrays.asList(strings));       
set.clear();

long forSet = timeIt(new Lambda() {
    @Override
    public void apply() {
        for (String string : strings) {
            set.add(string);
        }
    }
});

System.out.println("time: " + forSet);


Как и ожидалось, этот код выполняется точно так же долго, как и просто добавление без "разогрева": time: 1947486586

Я может не совсем понял мысль?
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Pahan : 745
Постоянный посетитель
Откуда: Минск

СообщениеОкт 20, 2011 12:04 
Ответить с цитатой
А что значит log(n), какое основание у этого логарифма?
К началу Посмотреть профиль Отправить личное сообщение
stolzen : 422
Бывалый
Откуда: Нижний Новгород

СообщениеОкт 20, 2011 12:13 
Ответить с цитатой
Pahan писал(а):
А что значит log(n), какое основание у этого логарифма?

[url]http://минимулин.рф/2/7.html[/url] Тут основание роли вообщем-то не играет (оценка приблизительная)
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора
abch-98-ru : 38
Новичок

СообщениеОкт 20, 2011 12:17 
Ответить с цитатой
Jean писал(а):
Сортировка коллекции, если это quick sort (кажется именно такой алгоритм реализован во встроенных коллекциях в Java),

не флейма ради, точности для.
в Collections.sort - merge sort. подозреваю из-за худшего случая.

по задаче " на скорость сортировки": тоже кажется, что сортирующая сеть побыстрее будет на компе, где больше одного процессора )
К началу Посмотреть профиль Отправить личное сообщение
Jean : 1992
JavaTalks Team Member
Откуда: Санкт-Петербург

СообщениеОкт 20, 2011 12:40 
Ответить с цитатой
Pahan писал(а):
А что значит log(n), какое основание у этого логарифма?

2
_________________
Всякое решение плодит новые проблемы
К началу Посмотреть профиль Отправить личное сообщение
Jean : 1992
JavaTalks Team Member
Откуда: Санкт-Петербург

СообщениеОкт 20, 2011 13:03 
Ответить с цитатой
stolzen писал(а):
Jean писал(а):
Вот, если бы исключить эти ребалансировку и все-таки начать измерения вемени со второго раза, результаты были бы вернее.

Возьметесь проверить?


Вы имеете ввиду, что нужно заранее подготовить несбалансированное множество записей, а затем на нем запустить балансировку? Думаю что не выйдет.

Хм... а ведь получается, что без перебалансировки-то дерево действительно не построишь.
Что ж, все мои аргументы побиты (они были ошибочными, вы это доказали). У меня других нет. =)
Видимо, результаты верные. Что означает, что все-таки для TreeMap вставка элемента стоит несколько дороже, чем logN. Из-за перебалансировки.

Другие мнения есть?
_________________
Всякое решение плодит новые проблемы
К началу Посмотреть профиль Отправить личное сообщение
Pahan : 745
Постоянный посетитель
Откуда: Минск

СообщениеОкт 20, 2011 13:04 
Ответить с цитатой
Jean писал(а):
OneHalf писал(а):
Не думаю, что сложность та же. Ведь когда добавляются элементы, то Log N надо считать от текущего значения N, а не от того, до которого коллекция должна вырасти.

Верно, но это записывается формулой Sum (log i), где i = от 1 до N. А сама эта формула приблизительно равна (NlogN - 1.5). То есть сложность все-таки NlogN.

Мне кажется что сума эта посчитана неверно, почему (N log N - 1.5)?

У нас n = 1000000.
1000000 log(1000000) запишем как сумму
log(1000000) + log(1000000) + log(1000000) + ... и так 1000000 раз

а сума запишется как
log(1) + log(2) + log(3) + ... и так до log(1000000)

Уже первые три члена сумы различаются намного больше чем на 1,5.
К началу Посмотреть профиль Отправить личное сообщение
Pahan : 745
Постоянный посетитель
Откуда: Минск

СообщениеОкт 20, 2011 13:19 
Ответить с цитатой
Мне кажется если прилично увеличить число строк, то в тесте который выше делали начнет побеждать TreeSet.
Проверьте кто-нить у ого под рукой Java.
К началу Посмотреть профиль Отправить личное сообщение
stolzen : 422
Бывалый
Откуда: Нижний Новгород

СообщениеОкт 20, 2011 13:54 
Ответить с цитатой
Pahan писал(а):
Мне кажется если прилично увеличить число строк, то в тесте который выше делали начнет побеждать TreeSet.
Проверьте кто-нить у ого под рукой Java.





Код:
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;

public class SomeClass {
   public static void main(String[] args) {
      
       final Integer[] ints = prepareInts();
       System.out.println("generated ints, sorting...");
      
       long forSet = timeIt(new Lambda() {
           @Override
           public void apply() {
               Set<Integer> set = new TreeSet<Integer>();
              
               for (Integer str : ints) {
                   set.add(str);
               }
           }
       });
      
       System.out.println("red-black tree: " + forSet);
      
       final List<Integer> list = new ArrayList<Integer>(Arrays.asList(ints));
      
       long forList = timeIt(new Lambda() {
           @Override
           public void apply() {
               Collections.sort(list);
           }
       });
      
       System.out.println("merge stable sort: " + forList);
   }

   private static Integer[] prepareInts() {
       int len = 10 * 1000 * 1000;
       final Integer[] ints = new Integer[len];
      
       Random random = new Random();
      
       for (int i = 0; i < len; ++i) {
          ints[i] = random.nextInt();
       }
      
       return ints;
   }

   static long timeIt(Lambda lambda) {
       long start = System.nanoTime();
       lambda.apply();
       long end = System.nanoTime();
       return end - start;
   }
}

interface Lambda {
   void apply();
}


generated ints, sorting...
red-black tree: 28315646410
merge stable sort: 6719941981
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Pahan : 745
Постоянный посетитель
Откуда: Минск

СообщениеОкт 20, 2011 15:08 
Ответить с цитатой
Добавил к тесту подсчет использования операции сравнения.

Код:
package my;

import java.util.Comparator;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;

public class Tester {
   public static void main(String[] args) {
      System.out.println("Generating of initial data.\n");
      final Integer[] ints = prepareInts();

      System.out.println("Testing of TreeSet...");
      long result = timeIt(new Lambda() {
         public void apply() {
            ComparatorCounter comparator = new ComparatorCounter();
            Set<Integer> set = new TreeSet<Integer>(comparator);
            for (Integer str : ints) {
               set.add(str);
            }
            System.out.println("Number of compaison: " + comparator.count() + ".");
         }
      });
      System.out.println("Time spent: " + result / 1000000000d + " sec\n");
      
      System.out.println("Testing of ArrayList + quicksort...");
      result = timeIt(new Lambda() {
         @Override
         public void apply() {
            ComparatorCounter comparator = new ComparatorCounter();
            List<Integer> list = new ArrayList<Integer>(Arrays.asList(ints));
            Collections.sort(list, comparator);

            System.out.println("Number of compaison: " + comparator.count());
         }
      });
      System.out.println("Time spent: " + result / 1000000000d + " sec\n");
   }

   private static Integer[] prepareInts() {
      int len = 1000 * 1000;
      final Integer[] ints = new Integer[len];

      Random random = new Random();

      for (int i = 0; i < len; ++i) {
         ints[i] = random.nextInt();
      }
      return ints;
   }

   static long timeIt(Lambda lambda) {
      long start = System.nanoTime();
      lambda.apply();
      long end = System.nanoTime();
      return end - start;
   }
}

interface Lambda {
   void apply();
}

class ComparatorCounter implements Comparator<Integer> {
   private int counter;

   @Override
   public int compare(Integer a, Integer b) {
      counter++;

      return a.compareTo(b);
   }

   public int count() {
      return counter;
   }
}


Результат при 1 000 000 записей:
Цитата:
Generating of initial data.

Testing of TreeSet...
Number of compaison: 18904363.
Time spent: 3.195978582 sec

Testing of ArrayList + quicksort...
Number of compaison: 18981114
Time spent: 1.4209246 sec


Запускал раз 10 количество операций сравнения всегда приблизительно равное, причем у TreeSet немножко меньше.
К началу Посмотреть профиль Отправить личное сообщение
Vurn : 1122
Java Developer

СообщениеОкт 20, 2011 17:49 
Ответить с цитатой
Pahan писал(а):
Запускал раз 10 количество операций сравнения всегда приблизительно равное, причем у TreeSet немножко меньше.


неудивительно. TreeSet постоянно при добавлении подсортировывает. При этом там реализовано B-Tree дерево, что вынуждает тратить дополнительное время на балансировку.
К началу Посмотреть профиль Отправить личное сообщение
Jean : 1992
JavaTalks Team Member
Откуда: Санкт-Петербург

СообщениеОкт 21, 2011 3:19 
Ответить с цитатой
Pahan писал(а):
Jean писал(а):
OneHalf писал(а):
Не думаю, что сложность та же. Ведь когда добавляются элементы, то Log N надо считать от текущего значения N, а не от того, до которого коллекция должна вырасти.

Верно, но это записывается формулой Sum (log i), где i = от 1 до N. А сама эта формула приблизительно равна (NlogN - 1.5). То есть сложность все-таки NlogN.

Мне кажется что сума эта посчитана неверно, почему (N log N - 1.5)?


http://www.imgup.ru/images/gz8x7561210.png
Взято из книги Макконнел - Основы современных алгоритмов, 2004. Страница (примерно) 26.
_________________
Всякое решение плодит новые проблемы
К началу Посмотреть профиль Отправить личное сообщение
HalfKorean : 88
Новичок

СообщениеОкт 27, 2011 16:37 
Ответить с цитатой
Сравнение функций.



Логарифмический масштаб


Частное функций


Правильная формула с суммой не NlogN - 1.5, а N(logN - 1.5). Что и дает разницу в 1.5N.

Видно, что массив в целом проигрывает, но чем больше количество объектов, тем разница менее существенна.
Результат тестов обратный потому, что эти функции показывают только количество операций сравнения. А у дерева много накладных расходов.
Для объектов со сложной функцией сравнения (или сложным компаратором) все было бы примерно так.

Мне кажется, деревья надо использовать для динамики. Для статичной одноразовой сортировки - классические методы.

Кстати, можно еще обратить внимание на то, что результат в виде массива эффективнее для вывода куда бы это ни было.
К началу Посмотреть профиль Отправить личное сообщение
den295 : 3
Новичок

СообщениеАпр 03, 2012 20:27 
Ответить с цитатой
Мне кажется что в Java вообще не актуально сравнивать какой из алгоритмов быстрее, так как в дело вмешивается GC, и не изветсно к в какой конкретно момент времени и сколько раз за каждый из циклов работы.

ИМХО в данном вопросе оптимальным решением было бы использовать Merge Sort, так доступ к строкам файла получается последовательно.
К началу Посмотреть профиль Отправить личное сообщение
abix : 12
Новичок

СообщениеАпр 05, 2012 10:53 
Ответить с цитатой
да уж. а что на собеседовании то отвечать?
К началу Посмотреть профиль Отправить личное сообщение
 
Начать новую тему  Ответить на тему
Страница 2 из 3
На страницу Пред.  1, 2, 3  След.
Список форумов
 -> Коллекции (Java Collection Framework)


 
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах


Java and all Java-related trademarks and logos are trademarks or registered trademarks of Oracle Corporation in the United States and other countries.
Это сайт не относится к фирме Oracle Corporation и не поддерживается ею.

© 2006-2010 www.javatalks.ru: форум java программистов
Используется скрипт phpBB © 2001, 2010 phpBB Group

Хостинг от bizname.ru