Effacer les filtres
Effacer les filtres

Fast UUID generation in matlab

78 vues (au cours des 30 derniers jours)
Simon Parten
Simon Parten le 29 Avr 2019
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???

Réponse acceptée

Simon Parten
Simon Parten le 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") }));
}
}
};

Plus de réponses (2)

Philipp Tempel
Philipp Tempel le 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

Simon Parten
Simon Parten le 2 Mai 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);

Catégories

En savoir plus sur Data Exchange and Mapping with C++ Applications dans Help Center et File Exchange

Tags

Produits

Community Treasure Hunt

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

Start Hunting!

Translated by