Трапеза: причина медленной инициализации

Я обнаружил, что инициализировать мою модель очень медленно. НА ЗАВЕРШЕНИЕ ТРЕБУЕТСЯ 40 СЕКУНД!

мои коды содержат две основные части: 1) считыватель данных CSV сначала запускается для загрузки данных, что занимает менее 1 секунды для завершения чтения и обработки более 35000 строк (см. код первой части ниже); 2) агент и ребра инициализируются впоследствии. В частности, инициализация ребер будет использовать загруженные данные в программе чтения CSV (см. Код второй части ниже).

Первая часть: код CSVReader

public class DataReader {

    private String csvFile;
    private List<String> sub = new ArrayList<String>();
    private List<List> master = new ArrayList<List>();


    public void ReadFromCSV(String csvFile) {

        String line = "";
        String cvsSplitBy = ",";

        try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {
            System.out.println("Header " + br.readLine());
            while ((line = br.readLine()) != null) {

                // use comma as separator
                String[] list = line.split(cvsSplitBy);
//                System.out.println("the size is " + country[1]);
                for (int i = 0; i < list.length; i++) {
                    sub.add(list[i]);
                }
                List<String> temp = (List<String>) ((ArrayList<String>) sub).clone();
//                master.add(new ArrayList<String>(sub));
                master.add(temp);
                sub.removeAll(sub);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println(master);
    }

    public List<List> getMaster() {
        return master;
    }

}

Это входной файл, используемый CSVReader:

введите описание изображения здесь

Вторая часть: код инициализации края (маршрута). Я подозреваю, что большую часть времени на инициализацию занимает цикл запроса:

//      add route network
        Network<Object> net = (Network<Object>)context.getProjection("IntraCity Network");
        IndexedIterable<Object> local_hubs = context.getObjects(LocalHub.class);
        for (int i = 0; i <= CSV_reader_route.getMaster().size() - 1; i++) {
            String source = (String) CSV_reader_route.getMaster().get(i).get(0);
            String target = (String) CSV_reader_route.getMaster().get(i).get(3);
            double dist = Double.parseDouble((String) CSV_reader_route.getMaster().get(i).get(6));
            double time = Double.parseDouble((String) CSV_reader_route.getMaster().get(i).get(7));

            Object source_hub = null;
            Object target_hub = null;
            Query<Object> source_query = new PropertyEquals<Object>(context, "hub_code", source);
            for (Object o : source_query.query()) {
                if (o instanceof LocalHub) {
                    source_hub = (LocalHub) o;
                }
                if (o instanceof GatewayHub) {
                    source_hub = (GatewayHub) o;
                }
            }

            Query<Object> target_query = new PropertyEquals<Object>(context, "hub_code", target);
            for (Object o : target_query.query()) {
                if (o instanceof LocalHub) {
                    target_hub = (LocalHub) o;
                }
                if (o instanceof GatewayHub) {
                    target_hub = (GatewayHub) o;
                }
            }

            if (net.getEdge(source_hub, target_hub) == null) {
                Route this_route = (Route) net.addEdge(source_hub, target_hub);
                context.add(this_route);
                this_route.setDist(dist);
                this_route.setTime(time); }
            }



        }

ОБНОВЛЕНИЕ: согласно моему тесту, я обнаружил, что эта строка резко замедляет процесс инициализации.

context.add(this_route);

Без этой строки для завершения требовалось всего 3 секунды. С этой строчкой модель заняла 20 секунд! Каков основной механизм context.add ()? Как решить и улучшить эту проблему?


person Jack    schedule 28.10.2019    source источник


Ответы (1)


Когда вы добавляете ребра в контекст, запросы становятся намного более затратными в вычислительном отношении, поскольку пространство поиска в контексте становится больше. Так что, возможно, не поможет добавление краев в контекст в цикле чтения csv. Вы можете создать край, как сейчас, но добавить его в список, а не в контекст. Затем, когда цикл чтения завершится, выполните итерацию по этому списку и добавьте края в контекст.

Если это не помогает, то, по крайней мере, мы знаем, что есть дополнительный побочный эффект при добавлении к контексту, который мы можем попытаться отследить.

person Nick Collier    schedule 28.10.2019
comment
Я последовал твоему предложению, и теперь это занимает 3 секунды. Но я не совсем понимаю. Когда вы добавляете ребра в контекст, запросы становятся намного более затратными в вычислительном отношении, поскольку пространство поиска в контексте становится больше. - запрос касается поиска агентов хаба, а не ребер, и, согласно моему тесту, он выполняется быстро. Почему context.add () в цикле DataReader замедляет скорость? - person Jack; 29.10.2019
comment
Можете ли вы сказать мне, есть ли какой-либо инструмент или метод тестирования скорости, который я мог бы использовать для тестирования определенной части кода? Мне часто нужен такой инструмент для оптимизации структуры модели, так как я часто имею дело с очень крупными системами, например система доставки посылок. - person Jack; 29.10.2019
comment
Запросы проходят итерацию по контексту - когда вы добавляете контекст, вы увеличиваете его, и, таким образом, поиск занимает больше времени, так как в контексте больше элементов для итерации. Java включает в себя инструмент visualvm или jvisualvm, который можно использовать для профилирования кода. - person Nick Collier; 30.10.2019