Help document for dictionary.insert misleading?

6 visualizaciones (últimos 30 días)
Alec Jacobson
Alec Jacobson el 31 de Mzo. de 2025
Respondida: Avni Agrawal el 3 de Abr. de 2025
The help document for dictionray.insert https://www.mathworks.com/help/matlab/ref/dictionary.insert.html writes that using
d = insert(d,key,value) is equivalent to d(key) = value.
But the performance seems asymptotically different.
As printed by this:
NS = 2.^(8:14);
T_insert = [];
T_paren = [];
D = dictionary();
for N = NS
% time repeated insertion
tic;
for i = 1:N
% Is this copying the dictionary every time?
D = D.insert(i,i);
end
T_insert = [T_insert;toc];
end
for N = NS
% time repeated insertion
for pass = 1:3
tic;
for i = 1:N
D(i) = i;
end
if pass == 3
T_paren = [T_paren;toc];
else
toc;
end
end
end
loglog(NS,T_insert,'LineWidth',2,'DisplayName','d = d.insert(key,…)');
hold on;
loglog(NS,T_paren,'LineWidth',2,'DisplayName','d(key) = …');
xlabel('Number of elements');
ylabel('Time (s)');
legend('show','FontSize',14,'Location','NorthWest');
set(gca,'FontSize',14);
hold off;
By the looks of it, I'd guess that d = d.insert(… is copying the entire dictionary every call. Whereas, d(…) = … seems to be changing the dictionary in place. Perhaps the documentation should not say that these are equivalent? Or, could anyone offer how I might be misunderstanding and they actually are?
> My follow up question (happy to repost separately), is how can I pass a dictionary to another function which updates it in the fast d(…) = … style? It seems like the copy-on-write function behavior will cause the copying to happen inside the function and the dictionary outside the call won't change. `containers.Map` doesn't seem to have this problem but it is also slower and less versitaile.

Respuestas (1)

Avni Agrawal
Avni Agrawal el 3 de Abr. de 2025
Your observations about the performance differences between `d = d.insert(key, value)` and `d(key) = value` are insightful. Here's a breakdown of what's happening and some guidance on your follow-up question:
Understanding the Performance Difference
  1. Copying Behavior: When you use `d = d.insert(key, value)`, it appears that the dictionary is being copied on each insertion. This is because you are reassigning the dictionary `d` to the result of `d.insert()`, which likely involves creating a new dictionary with the updated key-value pair. On the other hand, `d(key) = value` modifies the dictionary in place, which is more efficient because it avoids the overhead of copying the entire dictionary.
  2. Documentation Equivalence: The documentation might claim equivalence in terms of functionality (i.e., both methods achieve the same end result), but they are not equivalent in terms of performance due to the underlying implementation differences.
Passing a Dictionary to a Function
To update a dictionary within a function without incurring the overhead of copying, you can use the `d(key) = value` style within the function. Here's how you can achieve this:
function updateDictionary(d, key, value)
d(key) = value;
end
However, due to MATLAB's copy-on-write behavior, you need to ensure that the dictionary is modified in place. One way to do this is by using a handle class, which allows for in-place modifications.
Using Handle Class for In-Place Updates
You can create a simple handle class to wrap the dictionary:
classdef DictHandle < handle
properties
Data
end
methods
function obj = DictHandle()
obj.Data = dictionary();
end
function insert(obj, key, value)
obj.Data(key) = value;
end
end
end
Now, you can pass an instance of `DictHandle` to your function:
function updateDictionary(dHandle, key, value)
dHandle.insert(key, value);
end
% Usage
dHandle = DictHandle();
updateDictionary(dHandle, 'key1', 42);
disp(dHandle.Data)
The performance difference you observed is due to how `d = d.insert(...)` likely involves copying, whereas `d(key) = value` modifies the dictionary in place. By using a handle class, you can ensure that dictionary updates occur in place, avoiding unnecessary copying and improving performance. This approach should give you the speed and flexibility you need without switching to `containers.Map`.
I hope this helps!

Categorías

Más información sobre Class Introspection and Metadata en Help Center y File Exchange.

Etiquetas

Productos


Versión

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by