In
computer programming
Computer programming is the process of performing a particular computation (or more generally, accomplishing a specific computing result), usually by designing and building an executable computer program. Programming involves tasks such as anal ...
, 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. It is a kind of
lazy evaluation
In programming language theory, lazy evaluation, or call-by-need, is an evaluation strategy which delays the evaluation of an expression until its value is needed ( non-strict evaluation) and which also avoids repeated evaluations ( sharing).
T ...
that refers specifically to the instantiation of objects or other resources.
This is typically accomplished by augmenting an accessor method (or property getter) to check whether a private member, acting as a cache, has already been initialized. If it has, it is returned straight away. If not, a new instance is created, placed into the member variable, and returned to the caller just-in-time for its first use.
If objects have properties that are rarely used, this can improve startup speed. Mean average program performance may be slightly worse in terms of memory (for the condition variables) and execution cycles (to check them), but the impact of object instantiation is spread in time ("amortized") rather than concentrated in the startup phase of a system, and thus median response times can be greatly improved.
In
multithreaded code, access to lazy-initialized objects/state must be
synchronized to guard against
race condition
A race condition or race hazard is the condition of an electronics, software, or other system where the system's substantive behavior is dependent on the sequence or timing of other uncontrollable events. It becomes a bug when one or more of t ...
s.
The "lazy factory"
In a
software design pattern
In software engineering, a software design pattern is a general, reusable solution to a commonly occurring problem within a given context in software design. It is not a finished design that can be transformed directly into source or machine c ...
view, lazy initialization is often used together with a
factory method pattern. This combines three ideas:
* Using a factory method to create instances of a class (
factory method pattern)
* Storing the instances in a
map, and returning the ''same'' instance to each request for an instance with ''same'' parameters (
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
ActionScript is an object-oriented programming language originally developed by Macromedia Inc. (later acquired by Adobe). It is influenced by HyperTalk, the scripting language for HyperCard. It is now an implementation of ECMAScript (meani ...
:
package examples.lazyinstantiation
Basic Usage:
package
C
In C, lazy evaluation would normally be implemented inside a single function, or a single source file, using
static variable
In computer programming, a static variable is a variable that has been allocated "statically", meaning that its lifetime (or "extent") is the entire run of the program. This is in contrast to shorter-lived automatic variables, whose storage is ...
s.
In a function:
#include
#include
#include
#include
struct fruit ;
struct fruit *get_fruit(char *name)
/* Example code */
int main(int argc, char *argv[])
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 ;
struct fruit *get_fruit(char *name);
void print_fruit_list(FILE *file);
#endif /* _FRUIT_INCLUDED_ */
fruit.c:
#include
#include
#include
#include
#include "fruit.h"
static struct fruit *fruit_list;
static int seq;
struct fruit *get_fruit(char *name)
void print_fruit_list(FILE *file)
main.c:
#include
#include
#include "fruit.h"
int main(int argc, char *argv[])
C#
In .NET Framework 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
var lazyFruit = new Lazy();
Fruit fruit = lazyFruit.Value;
Here is a dummy example in
C#.
The
Fruit
class itself doesn't do anything here, The
class variable
In class-based, object-oriented programming, a class variable is a variable defined in a class of which a single copy exists, regardless of how many instances of the class exist.
A class variable is not an instance variable. It is a special ...
_typesDictionary
is a Dictionary/Map used to store
Fruit
instances by
typeName
.
using System;
using System.Collections;
using System.Collections.Generic;
public class Fruit
class Program
A fairly straightforward 'fill-in-the-blanks' example of a Lazy Initialization design pattern, except that this uses an
enumeration
An enumeration is a complete, ordered listing of all the items in a collection. The term is commonly used in mathematics and computer science to refer to a listing of all of the elements of a set. The precise requirements for an enumeration ( ...
for the type
namespace DesignPatterns.LazyInitialization;
public class LazyFactoryObject
C++
Here is an example in
C++.
#include
#include
Crystal
class Fruit
private getter type : String
@@types = of String => Fruit
def initialize(@type)
end
def self.get_fruit_by_type(type : String)
@@typesype
Peace River Airport is a municipally owned airport located west of the Town of Peace River, Alberta, Canada. The airport has one runway, which is , and a terminal building, which is .
Northern Air is based at the airport and provides scheduled ...
, , = Fruit.new(type)
end
def self.show_all
puts "Number of instances made: #"
@@types.each do , type, fruit,
puts "#"
end
puts
end
def self.size
@@types.size
end
end
Fruit.get_fruit_by_type("Banana")
Fruit.show_all
Fruit.get_fruit_by_type("Apple")
Fruit.show_all
Fruit.get_fruit_by_type("Banana")
Fruit.show_all
Output:
Number of instances made: 1
Banana
Number of instances made: 2
Banana
Apple
Number of instances made: 2
Banana
Apple
Haxe
Here is an example in
Haxe
Haxe is an open source high-level cross-platform programming language and compiler that can produce applications and source code, for many different computing platforms from one code-base. It is free and open-source software, released under the ...
class Fruit
Usage
class Test
Java
Here is an example in
Java
Java (; id, Jawa, ; jv, ꦗꦮ; su, ) is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea to the north. With a population of 151.6 million people, Java is the world's mo ...
.
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public class Program
enum FruitType
class Fruit
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
JavaScript (), often abbreviated as JS, is a programming language that is one of the core technologies of the World Wide Web, alongside HTML and CSS. As of 2022, 98% of Website, websites use JavaScript on the Client (computing), client side ...
.
var Fruit = (function() )();
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
PHP is a General-purpose programming language, general-purpose scripting language geared toward web development. It was originally created by Danish-Canadian programmer Rasmus Lerdorf in 1993 and released in 1995. The PHP reference implementati ...
7.4:
Python
Here is an example in Python.
class Fruit:
def __init__(self, item: str) -> None:
self.item = item
class Fruits:
def __init__(self) -> None:
self.items =
def get_fruit(self, item: str) -> Fruit:
if item not in self.items:
self.items tem= Fruit(item)
return self.items tem
if __name__ "__main__":
fruits = Fruits()
print(fruits.get_fruit("Apple"))
print(fruits.get_fruit("Lime"))
Ruby
Here is an example in Ruby
A ruby is a pinkish red to blood-red colored gemstone, a variety of the mineral corundum (aluminium oxide). Ruby is one of the most popular traditional jewelry gems and is very durable. Other varieties of gem-quality corundum are called sapp ...
, 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
In computing, memoization or memoisation is an optimization technique used primarily to speed up computer programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again. 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
Scala
Scala has built-in support for lazy variable initiation.
scala> val x =
Hello
x: Int = 99
scala> lazy val y =
y: Int =
scala> y
Hello!!
res2: Int = 31
scala> y
res3: Int = 31
Smalltalk
Here is an example in Smalltalk
Smalltalk is an object-oriented, dynamically typed reflective programming language. It was designed and created in part for educational use, specifically for constructionist learning, at the Learning Research Group (LRG) of Xerox PARC by ...
, of a typical accessor method In computer science, a mutator method is a method used to control changes to a variable. They are also widely known as setter methods. Often a setter is accompanied by a getter (together also known as accessors), which returns the value of the pri ...
to return the value of a variable using lazy initialization.
height
^height ifNil: eight := 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.
Theoretical computer science
In the field of theoretical computer science
Theoretical computer science (TCS) is a subset of general computer science and mathematics that focuses on mathematical aspects of computer science such as the theory of computation, lambda calculus, and type theory.
It is difficult to circumsc ...
, lazy initialization (also called a lazy array) is a technique to design data structure
In computer science, a data structure is a data organization, management, and storage format that is usually chosen for Efficiency, efficient Data access, access to data. More precisely, a data structure is a collection of data values, the rel ...
s that can work with memory that does not need to be initialized. Specifically, assume that we have access to a table ''T'' of ''n'' uninitialized memory cells (numbered from ''1'' to ''n''), and want to assign ''m'' cells of this array, e.g., we want to assign ''T'' i''">'ki'':= ''vi'' for pairs (''k''1, ''v''1), ..., (''km'', ''vm'') with all ''ki'' being different. The lazy initialization technique allows us to do this in just O(''m'') operations, rather than spending O(''m''+''n'') operations to first initialize all array cells. The technique is simply to allocate a table ''V'' storing the pairs (''ki'', ''vi'') in some arbitrary order, and to write for each ''i'' in the cell ''T'' i''">'ki''the position in ''V'' where key ''ki'' is stored, leaving the other cells of ''T'' uninitialized. This can be used to handle queries in the following fashion: when we look up cell ''T'' 'k''for some ''k'', we can check if ''k'' is in the range : if it is not, then ''T'' 'k''is uninitialized. Otherwise, we check ''V'' 'T''[''k'', and verify that the first component of this pair is equal to ''k''. If it is not, then ''T'' 'k''is uninitialized (and just happened by accident to fall in the range ). Otherwise, we know that ''T'' 'k''is indeed one of the initialized cells, and the corresponding value is the second component of the pair.
See also
* Double-checked locking
* Lazy loading
* Proxy pattern
* Singleton pattern
References
External links
* Article
Java Tip 67: Lazy instantiation
- Balancing performance and resource usage" by Philip Bishop
Philip, also Phillip, is a male given name, derived from the Greek (''Philippos'', lit. "horse-loving" or "fond of horses"), from a compound of (''philos'', "dear", "loved", "loving") and (''hippos'', "horse"). Prominent Philips who populariz ...
and Nigel Warren
Nigel ( ) is an English masculine given name.
The English ''Nigel'' is commonly found in records dating from the Middle Ages; however, it was not used much before being revived by 19th-century antiquarians. For instance, Walter Scott published ...
Java code examples
Use Lazy Initialization to Conserve Resources
Description from the Portland Pattern Repository
Lazy Inheritance in JavaScript
Lazy Inheritance in C#
{{DEFAULTSORT:Lazy Initialization
Software design patterns
Articles with example Java code