Fast UUID generation in matlab

82 views (last 30 days)
I want to generate some UUIDS.
function ids = makeUUIDs(num)
% idsJ = javaArray('java.util.UUID',num);
ids = strings(num,1);
for i = 1 : num
ids(i) = java.util.UUID.randomUUID;
end
% ids = arrayfun(@(x) string(x), idsJ);
% ids = jstring2string(ids);
end
Unfortunately, this is too slow for my liking
aTest= makeUUIDs(100000);
Takes 19.8 seconds... however, the actual generation in java takes 0.945 seconds according to the profiler. Can anyone thing of a faster way to do this???

Accepted Answer

Simon Parten
Simon Parten on 18 Oct 2019
The above was, in the end simply not fast enough. The below generates 1e6 UUIDS into a matlab string array, in 2.6s on my machine.
Much better.
Try this;
#include <iostream>
#include <string>
#include <list>
#include "MatlabDataArray.hpp"
#include "C:/temp/fastUUID/boost_1_71_0/boost_1_71_0/boost/uuid/uuid.hpp" // uuid class
#include "C:/temp/fastUUID/boost_1_71_0/boost_1_71_0/boost/uuid/uuid_generators.hpp" // generators
#include "C:/temp/fastUUID/boost_1_71_0/boost_1_71_0/boost/uuid/uuid_io.hpp" // streaming operators etc.
#include "C:/temp/fastUUID/boost_1_71_0/boost_1_71_0/boost/lexical_cast.hpp" // streaming operators etc.
#include "mex.hpp"
#include "mexAdapter.hpp"
using namespace matlab::data;
using matlab::mex::ArgumentList;
using namespace std;
// You'll need to install https://www.boost.org/
// The matlab cpp compiler
// And finally mex makeUuidArray.cpp -IC:\temp\fastUUID\boost_1_71_0\boost_1_71_0
class MexFunction : public matlab::mex::Function {
public:
void operator()(ArgumentList outputs, ArgumentList inputs) {
checkArguments(outputs, inputs);
const int numIds = inputs[0][0];
ArrayFactory factory;
boost::uuids::random_generator generator;
boost::uuids::uuid uuid1;
// Three variables for the string vector, tempstring, tempUUID
TypedArray<MATLABString> results = factory.createArray<MATLABString>({ numIds,1 });
for (auto elem : results) {
uuid1 = generator();
elem = boost::lexical_cast<std::string>(uuid1) ;
}
outputs[0] = results ;
}
void checkArguments(ArgumentList outputs, ArgumentList inputs) {
std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine();
ArrayFactory factory;
// Check first input argument
if (inputs[0].getType() != ArrayType::DOUBLE ||
inputs[0].getType() == ArrayType::COMPLEX_DOUBLE ||
inputs[0].getNumberOfElements() != 1)
{
matlabPtr->feval(u"error",
0,
std::vector<Array>({ factory.createScalar("First input must be scalar double") }));
}
// Check number of outputs
if (outputs.size() > 1) {
matlabPtr->feval(u"error",
0,
std::vector<Array>({ factory.createScalar("Only one output is returned") }));
}
}
};

More Answers (2)

Simon Parten
Simon Parten on 2 May 2019
This is my best solution
idsJ = javaArray('java.lang.String',num);
ids = strings(num,1);
for i = 1 : num
idsJ(i) = javaMethod('toString', java.util.UUID.randomUUID);
end
ids = string(idsJ);

Philipp Tempel
Philipp Tempel on 17 Mar 2022
This may be too stupid to be true but, looking at the source code of tempname(), you can see that you can simply do
uuid = char(matlab.lang.internal.uuid())
It's not as fast as @Simon Parten's solution (about one magnitude slower), but it at least doesn't require compiling C-code and it uses only built-in MATLAB functions.
Stats:
Trial1
runs: 1e6
sum: 18s 316.259ms
min: 15.1694mus
median: 17mus
mean: 18mus
max: 702.108402mus
std: 5.847mus

Tags

Products

Community Treasure Hunt

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

Start Hunting!