From 5b235ab1f82373a7a7fd146a0e1b2b592ccaa2a1 Mon Sep 17 00:00:00 2001 From: Joerg Riesmeier Date: Wed, 30 Oct 2024 17:47:07 +0100 Subject: [PATCH] Improved performance of DcmVR::setVR(). When creating and processing very large amounts of DICOM data sets, the implementation of DcmVR::setVR() could have led to a performance bottleneck, so it was improved, e.g. by avoiding the call of strncmp() for comparing the two-letter VR codes. Thanks to Jesper Alf Dam for the report, the performance analysis and the original patch. --- dcmdata/libsrc/dcvr.cc | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/dcmdata/libsrc/dcvr.cc b/dcmdata/libsrc/dcvr.cc index 169069f69f..5f4d393874 100644 --- a/dcmdata/libsrc/dcvr.cc +++ b/dcmdata/libsrc/dcvr.cc @@ -225,20 +225,24 @@ void DcmVR::setVR(const char* vrName) { vr = EVR_UNKNOWN; /* default */ - if (vrName != NULL) + /* Make sure that the passed character string is not empty */ + if ((vrName != NULL) && (*vrName != '\0')) { - int found = OFFalse; - int i = 0; - for (i = 0; (!found && (i < DcmVRDict_DIM)); i++) + /* Extract the first two characters from the passed string */ + const char c1 = *vrName; + const char c2 = *(vrName + 1); + OFBool found = OFFalse; + for (int i = 0; i < DcmVRDict_DIM; i++) { - /* We only compare the first two characters of the passed string and - * never accept a VR that is labeled for internal use only. + /* We only compare the first two characters of the passed string + * and never accept a VR that is labeled for internal use only. */ - if ((strncmp(vrName, DcmVRDict[i].vrName, 2) == 0) && + if ((DcmVRDict[i].vrName[0] == c1) && (DcmVRDict[i].vrName[1] == c2) && !(DcmVRDict[i].propertyFlags & DCMVR_PROP_INTERNAL)) { found = OFTrue; vr = DcmVRDict[i].vr; + break; } } /* Workaround: There have been reports of systems transmitting @@ -250,8 +254,6 @@ DcmVR::setVR(const char* vrName) * letters as "real" future VRs (and thus assume extended length). * All other VR strings are treated as "illegal" VRs. */ - char c1 = *vrName; - char c2 = (c1) ? (*(vrName + 1)) : ('\0'); if ((c1 == '?') && (c2 == '?')) vr = EVR_UNKNOWN2B; if (!found && ((c1 < 'A') || (c1 > 'Z') || (c2 < 'A') || (c2 > 'Z'))) vr = EVR_UNKNOWN2B; }