Что такое ленивая инициализация и почему это полезно?

Для MySQL используйте бедный человек generate_series , который делается через представления. MySQL - единственная СУБД среди большой четверки , у которой нет функции CTE.

На самом деле вы можете использовать эту технику в базе данных, которая поддерживает просмотр. Таким образом, это практически вся база данных

Техника генерации здесь: http://use-the-index-luke.com/blog/2011-07-30/mysql-row-generator#mysql_generator_code

Единственная незначительная модификация, которую мы сделали, - мы заменили битовую ( сдвиг влево и битовую или ) оригинальную технику простым умножением и сложением соответственно; поскольку у сервера Sql и Oracle нет оператора сдвига влево.

Эта абстракция гарантированно на 99% работает на всех базах данных, кроме Oracle; Oracle SELECT не может функционировать без какой-либо таблицы, для этого нужно выбрать фиктивную таблицу, Oracle уже предоставил одну, она называется DUAL table. Переносимость базы данных - несбыточная мечта: -)

Вот абстрагированные представления, работающие на всех RDBMS, лишенные побитовых операций (которые в любом случае не являются необходимостью в этом сценарии) и нюансы функций (мы удаляем OR REPLACE на CREATE VIEW только Postgresql и MySQL поддерживают их) из всех основных баз данных.

Предупреждение Oracle: просто ставьте FROM DUAL после каждого SELECT выражения

CREATE VIEW generator_16
AS SELECT 0 n UNION ALL SELECT 1  UNION ALL SELECT 2  UNION ALL 
   SELECT 3   UNION ALL SELECT 4  UNION ALL SELECT 5  UNION ALL
   SELECT 6   UNION ALL SELECT 7  UNION ALL SELECT 8  UNION ALL
   SELECT 9   UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL
   SELECT 12  UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL 
   SELECT 15;

CREATE VIEW generator_256
AS SELECT ( ( hi.n * 16 ) + lo.n ) AS n
     FROM generator_16 lo, generator_16 hi;

CREATE VIEW generator_4k
AS SELECT ( ( hi.n * 256 ) + lo.n ) AS n
     FROM generator_256 lo, generator_16 hi;

CREATE VIEW generator_64k
AS SELECT ( ( hi.n * 256 ) + lo.n ) AS n
     FROM generator_256 lo, generator_256 hi;

CREATE VIEW generator_1m
AS SELECT ( ( hi.n * 65536 ) + lo.n ) AS n
     FROM generator_64k lo, generator_16 hi;

Затем используйте этот запрос:

SELECT t.value, t.cnt, i.n
FROM tbl t
JOIN generator_64k i 
ON i.n between 1 and t.cnt
order by t.value, i.n

Postgresql: http: //www.sqlfiddle.com/#!1/1541d/1

Oracle: http://www.sqlfiddle.com/#!4/26c05/1

Сервер Sql: http://www.sqlfiddle.com/#!6/84bee/1

MySQL: http: //www.sqlfiddle. ком / #! 2 / 78f5b / 1

69
задан SNA 16 March 2012 в 22:45
поделиться

6 ответов

Ленивая инициализация - это оптимизация производительности, при которой вы откладываете (потенциально дорогое) создание объекта до тех пор, пока он вам не понадобится.

Хороший пример - не создавать соединение с базой данных заранее, а только непосредственно перед тем, как вам понадобится получить данные из базы данных.

Основная причина этого состоит в том, что (часто) вы можете полностью избежать создания объекта, если он вам никогда не понадобится.

89
ответ дан 24 November 2019 в 13:43
поделиться

Ленивая инициализация - это концепция откладывания создания объекта до фактического использования объекта. При правильном использовании это может привести к значительному увеличению производительности.

Лично я использовал отложенную инициализацию при создании моей собственной ORM, созданной вручную в .NET 2.0. При загрузке моих коллекций из базы данных фактические элементы в коллекции были инициализированы лениво. Это означало, что коллекции создавались быстро, но каждый объект загружался только тогда, когда это требовалось мне.

Если вы знакомы с шаблоном Singleton, вы, вероятно, также видели в действии ленивую инициализацию.

public class SomeClassSingleton
{
    private static SomeClass _instance = null;

    private SomeClassSingleton()
    {
    }

    public static SomeClass GetInstance()
    {
        if(_instance == null)
            _instance = new SomeClassSingleton();

        return _instance;
    }
}

В этом кейс,

14
ответ дан 24 November 2019 в 13:43
поделиться

Как уже упоминалось, ленивая инициализация откладывает инициализацию до тех пор, пока не будет использован компонент или объект. Вы можете рассматривать отложенную инициализацию как приложение времени выполнения принципа YAGNI - « Вам это не понадобится »

Преимущества с точки зрения приложения Из-за ленивой инициализации пользователям не нужно платить за время инициализации для функций, которые они не будут использовать. Предположим, вы должны инициализировать каждый компонент своего приложения заранее. Это может создать потенциально долгое время запуска - пользователям придется ждать десятки секунд или минут, прежде чем ваше приложение будет готово к использованию. Они ждут и платят за инициализацию функций, которые могут никогда не использовать или не использовать сразу.

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

42
ответ дан 24 November 2019 в 13:43
поделиться

В общих вычислительных терминах «ленивая оценка» означает откладывание обработки чего-либо до тех пор, пока оно вам действительно не понадобится. Основная идея заключается в том, что иногда можно избежать дорогостоящих операций, если он окажется вам не нужен или если значение изменится до того, как вы его начнете использовать.

Простым примером этого является System.Exception.StackTrace. Это строковое свойство исключения, но на самом деле оно не создается, пока вы не получите к нему доступ. Внутри он делает что-то вроде:

String StackTrace{
  get{
    if(_stackTrace==null){
      _stackTrace = buildStackTrace();
    }
    return _stackTrace;
  }
}

Это избавляет вас от накладных расходов, связанных с вызовом buildStackTrace до тех пор, пока кто-то не захочет увидеть, что это такое.

Свойства - это один из способов просто обеспечить такой тип поведения.

5
ответ дан 24 November 2019 в 13:43
поделиться

Насколько я понял о ленивом init, программа не загружает / не запрашивает все данные за один раз. Он ожидает его использования, прежде чем запрашивать его, например. SQL-сервер.

Если у вас есть база данных с большой таблицей, соединенной с большим количеством подтаблиц, и вам не требуются детали, присоединенные из других таблиц, если вы не входите в «редактировать» или «просматривать детали», тогда Lazy Init . поможет приложению работать быстрее и сначала «лениво загружать» подробные данные при необходимости.

В SQL или LINQ вы можете установить эту «настройку» в вашей модели базы данных pr. dataelement.

Надеюсь, это имеет какое-то значение для вашего вопроса?

Веб-клиент (например, браузер) делает то же самое. Изображения "лениво загружаются" после HTML, и AJAX также является "разновидностью ленивой инициализации" при правильном использовании.

1
ответ дан 24 November 2019 в 13:43
поделиться

The database examples that have been mentioned so far are good, but it's not restricted to just the data access layer. You could apply the same principles to any situation where performance or memory can be a concern. A good example (although not .NET) is in Cocoa, where you can wait until the user requests a window to actually load it (and its associated objects) from the nib. This can help keep memory usage down and speed up the initial application load, especially when you're talking about things like Preferences windows that won't be needed until some later time, if ever.

1
ответ дан 24 November 2019 в 13:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: