필터 지우기
필터 지우기

Fast UUID generation in matlab

조회 수: 78 (최근 30일)
Simon Parten
Simon Parten 2019년 4월 29일
답변: Philipp Tempel 2022년 3월 17일
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???

채택된 답변

Simon Parten
Simon Parten 2019년 10월 18일
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") }));
}
}
};

추가 답변 (2개)

Philipp Tempel
Philipp Tempel 2022년 3월 17일
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 2019년 5월 2일
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);

카테고리

Help CenterFile Exchange에서 Data Exchange and Mapping with C++ Applications에 대해 자세히 알아보기

태그

제품

Community Treasure Hunt

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

Start Hunting!

Translated by