Lazy initialization
In computer programming, lazy initialization is the tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed.
This is typically accomplished by augmenting a variable's accessor method (or property definition) to check for a previously-created instance. If none exists a new instance is created, placed into the variable, and this new object is returned to the caller in a just-in-time fashion. In this manner object creation is deferred until first use which can, in some circumstances (e.g., sporadic object access), increase system responsiveness and speed startup by bypassing large-scale object pre-allocation. (Note that this may have attendant counter-effects on overall performance, however, as the impact of object instantiation is then amortized across the startup/warm-up phase of the system.)
In multithreaded code, access to lazy-initialized objects/state must be synchronized to guard against a race condition.
See lazy evaluation for a general treatment of this idea. In heavily imperative languages this pattern carries hidden dangers, as does any programming habit that relies on shared state.
The "lazy factory"
In a software design pattern view, lazy initialization is often used together with a factory method pattern. This combines three ideas:
- Using a factory method to get instances of a class (factory method pattern)
- Store the instances in a map, so you get the same instance the next time you ask for an instance with same parameter (multiton pattern)
- Using lazy initialization to instantiate the object the first time it is requested (lazy initialization pattern)
Examples
Actionscript 3
The following is an example of a class with Lazy initialization implemented in Actionscript:
package examples.lazyinstantiation
{
public class Fruit
{
private var _typeName:String;
private static var instancesByTypeName:Dictionary = new Dictionary();
public function Fruit(typeName:String):void
{
this._typeName = typeName;
}
public function get typeName():String
{
return _typeName;
}
public static function getFruitByTypeName(typeName:String):Fruit
{
return instancesByTypeName[typeName] ||= new Fruit(typeName);
}
public static function printCurrentTypes():void
{
for each (var fruit:Fruit in instancesByTypeName)
{
// iterates through each value
trace(fruit.typeName);
}
}
}
}
Basic Usage:
package
{
import examples.lazyinstantiation;
public class Main
{
public function Main():void
{
Fruit.getFruitByTypeName("Banana");
Fruit.printCurrentTypes();
Fruit.getFruitByTypeName("Apple");
Fruit.printCurrentTypes();
Fruit.getFruitByTypeName("Banana");
Fruit.printCurrentTypes();
}
}
}
C
In C, lazy evaluation would normally be implemented inside a single function, or a single source file, using static variables.
In a function:
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
struct fruit {
char *name;
struct fruit *next;
int number;
/* Other members */
};
struct fruit *get_fruit(char *name) {
static struct fruit *fruit_list;
static int seq;
struct fruit *f;
for (f = fruit_list; f; f = f->next)
if (0 == strcmp(name, f->name))
return f;
if (!(f = malloc(sizeof(struct fruit))))
return NULL;
if (!(f->name = strdup(name))) {
free(f);
return NULL;
}
f->number = ++seq;
f->next = fruit_list;
fruit_list = f;
return f;
}
/* Example code */
int main(int argc, char *argv[]) {
int i;
struct fruit *f;
if (argc < 2) {
fprintf(stderr, "Usage: fruits fruit-name [...]\n");
exit(1);
}
for (i = 1; i < argc; i++) {
if ((f = get_fruit(argv[i]))) {
printf("Fruit %s: number %d\n", argv[i], f->number);
}
}
return 0;
}
Using a single source file instead allows the state to be shared between multiple functions, while still hiding it from non-related functions.
fruit.h:
#ifndef _FRUIT_INCLUDED_
#define _FRUIT_INCLUDED_
struct fruit {
char *name;
struct fruit *next;
int number;
/* Other members */
};
struct fruit *get_fruit(char *name);
void print_fruit_list(FILE *file);
#endif /* _FRUIT_INCLUDED_ */
fruit.c:
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include "fruit.h"
static struct fruit *fruit_list;
static int seq;
struct fruit *get_fruit(char *name) {
struct fruit *f;
for (f = fruit_list; f; f = f->next)
if (0 == strcmp(name, f->name))
return f;
if (!(f = malloc(sizeof(struct fruit))))
return NULL;
if (!(f->name = strdup(name))) {
free(f);
return NULL;
}
f->number = ++seq;
f->next = fruit_list;
fruit_list = f;
return f;
}
void print_fruit_list(FILE *file) {
struct fruit *f;
for (f = fruit_list; f; f = f->next)
fprintf(file, "%4d %s\n", f->number, f->name);
}
main.c:
#include <stdlib.h>
#include <stdio.h>
#include "fruit.h"
int main(int argc, char *argv[]) {
int i;
struct fruit *f;
if (argc < 2) {
fprintf(stderr, "Usage: fruits fruit-name [...]\n");
exit(1);
}
for (i = 1; i < argc; i++) {
if ((f = get_fruit(argv[i]))) {
printf("Fruit %s: number %d\n", argv[i], f->number);
}
}
printf("The following fruits have been generated:\n");
print_fruit_list(stdout);
return 0;
}
C#
In .NET 4.0 Microsoft has included a Lazy
class that can be used to do lazy loading.
Below is some dummy code that does lazy loading of Class Fruit
Lazy<Fruit> lazyFruit = new Lazy<Fruit>();
Fruit fruit = lazyFruit.Value;
Here is a dummy example in C#.
The Fruit
class itself doesn't do anything here, The class variable _typesDictionary
is a Dictionary/Map used to store Fruit
instances by typeName
.
using System;
using System.Collections;
using System.Collections.Generic;
public class Fruit
{
private string _typeName;
private static Dictionary<string, Fruit> _typesDictionary = new Dictionary<string, Fruit>();
private Fruit(String typeName)
{
this._typeName = typeName;
}
public static Fruit GetFruitByTypeName(string type)
{
Fruit fruit;
if (!_typesDictionary.TryGetValue(type, out fruit))
{
// Lazy initialization
fruit = new Fruit(type);
_typesDictionary.Add(type, fruit);
}
return fruit;
}
public static void ShowAll()
{
if (_typesDictionary.Count > 0)
{
Console.WriteLine("Number of instances made = {0}", _typesDictionary.Count);
foreach (KeyValuePair<string, Fruit> kvp in _typesDictionary)
{
Console.WriteLine(kvp.Key);
}
Console.WriteLine();
}
}
public Fruit()
{
// required so the sample compiles
}
}
class Program
{
static void Main(string[] args)
{
Fruit.GetFruitByTypeName("Banana");
Fruit.ShowAll();
Fruit.GetFruitByTypeName("Apple");
Fruit.ShowAll();
// returns pre-existing instance from first
// time Fruit with "Banana" was created
Fruit.GetFruitByTypeName("Banana");
Fruit.ShowAll();
Console.ReadLine();
}
}
A fairly straightforward 'fill-in-the-blanks' example of a Lazy Initialization design pattern, except that this uses an enumeration for the type
namespace DesignPatterns.LazyInitialization
{
public class LazyFactoryObject
{
//internal collection of items
//IDictionaery makes sure they are unique
private IDictionary<LazyObjectType, LazyObject> _LazyObjectList =
new Dictionary<LazyObjectType, LazyObject>();
//enum for passing name of type required
//avoids passing strings and is part of type ahead
public enum LazyObjectType
{
None,
Small,
Big,
Bigger,
Huge
}
//standard type of object that will be constructed
public struct LazyObject
{
public LazyObjectType Name;
public IList<int> Result;
}
//takes type and create 'expensive' list
private IList<int> Result(LazyObjectType name)
{
IList<int> result = null;
switch (name)
{
case LazyObjectType.Small:
result = CreateSomeExpensiveList(1, 100);
break;
case LazyObjectType.Big:
result = CreateSomeExpensiveList(1, 1000);
break;
case LazyObjectType.Bigger:
result = CreateSomeExpensiveList(1, 10000);
break;
case LazyObjectType.Huge:
result = CreateSomeExpensiveList(1, 100000);
break;
case LazyObjectType.None:
result = null;
break;
default:
result = null;
break;
}
return result;
}
//not an expensive item to create, but you get the point
//delays creation of some expensive object until needed
private IList<int> CreateSomeExpensiveList(int start, int end)
{
IList<int> result = new List<int>();
for (int counter = 0; counter < (end - start); counter++)
{
result.Add(start + counter);
}
return result;
}
public LazyFactoryObject()
{
//empty constructor
}
public LazyObject GetLazyFactoryObject(LazyObjectType name)
{
//yes, i know it is illiterate and inaccurate
LazyObject noGoodSomeOne;
//retrieves LazyObjectType from list via out, else creates one and adds it to list
if (!_LazyObjectList.TryGetValue(name, out noGoodSomeOne))
{
noGoodSomeOne = new LazyObject();
noGoodSomeOne.Name = name;
noGoodSomeOne.Result = this.Result(name);
_LazyObjectList.Add(name, noGoodSomeOne);
}
return noGoodSomeOne;
}
}
}
C++
Here is an example in C++.
#include <iostream>
#include <string>
#include <map>
using namespace std;
class Fruit {
public:
static Fruit* getFruit(const string& type);
static void printCurrentTypes();
private:
static map<string,Fruit*> types;
string type;
// note: constructor private forcing one to use static getFruit()
Fruit(const string& t) : type( t ) {}
};
//definition needed for using any static member variable
map<string,Fruit*> Fruit::types;
/*
* Lazy Factory method, gets the Fruit instance associated with a
* certain type. Instantiates new ones as needed.
* precondition: type. Any string that describes a fruit type, e.g. "apple"
* postcondition: The Fruit instance associated with that type.
*/
Fruit* Fruit::getFruit(const string& type) {
map<string,Fruit*>::iterator it = types.find(type); // try to find an existing instance; if not found std::map will return types.end()
Fruit *f;
if (it == types.end()) { // if no instance with the proper type was found, make one
f = new Fruit(type); // lazy initialization part
types[type] = f; // adding the newly created Fruit to the types map for later lookup
} else { //if already had an instance
f = it->second; //The return value will be the found fruit
}
return f;
}
/*
* For example purposes to see pattern in action
*/
void Fruit::printCurrentTypes() {
if (!types.empty()) {
cout << "Number of instances made = " << types.size() << endl;
for (map<string,Fruit*>::iterator iter = types.begin(); iter != types.end(); ++iter) {
cout << (*iter).first << endl;
}
cout << endl;
}
}
int main(void) {
Fruit::getFruit("Banana");
Fruit::printCurrentTypes();
Fruit::getFruit("Apple");
Fruit::printCurrentTypes();
// returns pre-existing instance from first
// time Fruit with "Banana" was created
Fruit::getFruit("Banana");
Fruit::printCurrentTypes();
return 0;
}
/*
OUTPUT:
Number of instances made = 1
Banana
Number of instances made = 2
Apple
Banana
Number of instances made = 2
Apple
Banana
*/
Java
Here is an example in Java.
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public class Program {
/**
* @param args
*/
public static void main(String[] args) {
Fruit.getFruitByTypeName(FruitType.banana);
Fruit.showAll();
Fruit.getFruitByTypeName(FruitType.apple);
Fruit.showAll();
Fruit.getFruitByTypeName(FruitType.banana);
Fruit.showAll();
}
}
enum FruitType {
none,
apple,
banana,
}
class Fruit {
private static Map<FruitType, Fruit> types = new HashMap<>();
/**
* Using a private constructor to force the use of the factory method.
* @param type
*/
private Fruit(FruitType type) {
}
/**
* Lazy Factory method, gets the Fruit instance associated with a certain
* type. Instantiates new ones as needed.
* @param type Any allowed fruit type, e.g. APPLE
* @return The Fruit instance associated with that type.
*/
public static Fruit getFruitByTypeName(FruitType type) {
Fruit fruit;
// This has concurrency issues. Here the read to types is not synchronized,
// so types.put and types.containsKey might be called at the same time.
// Don't be surprised if the data is corrupted.
if (!types.containsKey(type)) {
// Lazy initialisation
fruit = new Fruit(type);
types.put(type, fruit);
} else {
// OK, it's available currently
fruit = types.get(type);
}
return fruit;
}
/**
* Lazy Factory method, gets the Fruit instance associated with a certain
* type. Instantiates new ones as needed. Uses double-checked locking
* pattern for using in highly concurrent environments.
* @param type Any allowed fruit type, e.g. APPLE
* @return The Fruit instance associated with that type.
*/
public static Fruit getFruitByTypeNameHighConcurrentVersion(FruitType type) {
if (!types.containsKey(type)) {
synchronized (types) {
// Check again, after having acquired the lock to make sure
// the instance was not created meanwhile by another thread
if (!types.containsKey(type)) {
// Lazy initialisation
types.put(type, new Fruit(type));
}
}
}
return types.get(type);
}
/**
* Displays all entered fruits.
*/
public static void showAll() {
if (types.size() > 0) {
System.out.println("Number of instances made = " + types.size());
for (Entry<FruitType, Fruit> entry : types.entrySet()) {
String fruit = entry.getKey().toString();
fruit = Character.toUpperCase(fruit.charAt(0)) + fruit.substring(1);
System.out.println(fruit);
}
System.out.println();
}
}
}
Output
Number of instances made = 1 Banana Number of instances made = 2 Banana Apple Number of instances made = 2 Banana Apple
JavaScript
Here is an example in JavaScript.
var Fruit = (function() {
var types = {};
function Fruit() {};
// count own properties in object
function count(obj) {
return Object.keys(obj).length;
}
var _static = {
getFruit: function(type) {
if (typeof types[type] == 'undefined') {
types[type] = new Fruit;
}
return types[type];
},
printCurrentTypes: function () {
console.log('Number of instances made: ' + count(types));
for (var type in types) {
console.log(type);
}
}
};
return _static;
})();
Fruit.getFruit('Apple');
Fruit.printCurrentTypes();
Fruit.getFruit('Banana');
Fruit.printCurrentTypes();
Fruit.getFruit('Apple');
Fruit.printCurrentTypes();
Output
Number of instances made: 1 Apple Number of instances made: 2 Apple Banana Number of instances made: 2 Apple Banana
PHP
Here is an example of lazy initialization in PHP 5:
<?php
header('Content-type:text/plain; charset=utf-8');
class Fruit {
private $type;
private static $types = array();
private function __construct($type) {
$this->type = $type;
}
public static function getFruit($type) {
// Lazy initialization takes place here
if (!isset(self::$types[$type])) {
self::$types[$type] = new Fruit($type);
}
return self::$types[$type];
}
public static function printCurrentTypes() {
echo 'Number of instances made: ' . count(self::$types) . "\n";
foreach (array_keys(self::$types) as $key) {
echo "$key\n";
}
echo "\n";
}
}
Fruit::getFruit('Apple');
Fruit::printCurrentTypes();
Fruit::getFruit('Banana');
Fruit::printCurrentTypes();
Fruit::getFruit('Apple');
Fruit::printCurrentTypes();
/*
OUTPUT:
Number of instances made: 1
Apple
Number of instances made: 2
Apple
Banana
Number of instances made: 2
Apple
Banana
*/
?>
Python
Here is an example in Python.
class Fruit:
def __init__(self, item):
self.item = item
class Fruits:
def __init__(self):
self.items = {}
def get_fruit(self, item):
if item not in self.items:
self.items[item] = Fruit(item)
return self.items[item]
if __name__ == '__main__':
fruits = Fruits()
print(fruits.get_fruit('Apple'))
print(fruits.get_fruit('Lime'))
Ruby
Here is an example in Ruby, of lazily initializing an authentication token from a remote service like Google. The way that @auth_token is cached is also an example of memoization.
require 'net/http'
class Blogger
def auth_token
@auth_token ||=
(res = Net::HTTP.post_form(uri, params)) &&
get_token_from_http_response(res)
end
# get_token_from_http_response, uri and params are defined later in the class
end
b = Blogger.new
b.instance_variable_get(:@auth_token) # returns nil
b.auth_token # returns token
b.instance_variable_get(:@auth_token) # returns token
Smalltalk
Here is an example in Smalltalk, of a typical accessor method to return the value of a variable using lazy initialization.
height
^height ifNil: [height := 2.0].
The 'non-lazy' alternative is to use an initialization method that is run when the object is created and then use a simpler accessor method to fetch the value.
initialize
height := 2.0
height
^height
Note that lazy initialization can also be used in non-object-oriented languages.
Scala
Scala has built-in support for lazy variable initiation.[1]
scala> val x = { println("Hello"); 99 }
Hello
x: Int = 99
scala> lazy val y = { println("Hello!!"); 31 }
y: Int = <lazy>
scala> y
Hello!!
res2: Int = 31
scala> y
res3: Int = 31
See also
References
External links
- Article "Java Tip 67: Lazy instantiation - Balancing performance and resource usage" by Philip Bishop and Nigel Warren
- Java code examples
- Use Lazy Initialization to Conserve Resources
- Description from the Portland Pattern Repository
- Lazy Initialization of Application Server Services
- Lazy Inheritance in JavaScript
- Lazy Inheritance in C#