diff --git a/vendor/magento/module-elasticsearch/Model/Adapter/BatchDataMapper/ProductDataMapper.php b/vendor/magento/module-elasticsearch/Model/Adapter/BatchDataMapper/ProductDataMapper.php
index 0edc63b10f9a..a9fb67f209aa 100644
--- a/vendor/magento/module-elasticsearch/Model/Adapter/BatchDataMapper/ProductDataMapper.php
+++ b/vendor/magento/module-elasticsearch/Model/Adapter/BatchDataMapper/ProductDataMapper.php
@@ -370,8 +370,11 @@ private function getValuesLabels(Attribute $attribute, array $attributeValues, i
             return $attributeLabels;
         }
 
+        // array_flip() + foreach { isset() }  is much faster than foreach { in_array() } when there are many options
+        $attributeValues = array_flip($attributeValues);
+
         foreach ($options as $option) {
-            if (\in_array($option['value'], $attributeValues)) {
+            if (isset($attributeValues[$option['value']])) {
                 $attributeLabels[] = $option['label'];
             }
         }
diff --git a/vendor/magento/framework/Webapi/ServiceInputProcessor.php b/vendor/magento/framework/Webapi/ServiceInputProcessor.php
index a5e881f4be54..ea5a4274196a 100644
--- a/vendor/magento/framework/Webapi/ServiceInputProcessor.php
+++ b/vendor/magento/framework/Webapi/ServiceInputProcessor.php
@@ -101,6 +101,11 @@ class ServiceInputProcessor implements ServicePayloadConverterInterface
      */
     private $defaultPageSizeSetter;
 
+    /**
+     * @var array
+     */
+    private $methodReflectionStorage = [];
+
     /**
      * Initialize dependencies.
      *
@@ -153,6 +158,7 @@ public function __construct(
      * @return \Magento\Framework\Reflection\NameFinder
      *
      * @deprecated 100.1.0
+     * @see nothing
      */
     private function getNameFinder()
     {
@@ -260,6 +266,7 @@ private function getConstructorData(string $className, array $data): array
      * @return object the newly created and populated object
      * @throws \Exception
      * @throws SerializationException
+     * @SuppressWarnings(PHPMD.NPathComplexity)
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      */
     protected function _createFromArray($className, $data)
@@ -286,35 +293,42 @@ protected function _createFromArray($className, $data)
             // Converts snake_case to uppercase CamelCase to help form getter/setter method names
             // This use case is for REST only. SOAP request data is already camel cased
             $camelCaseProperty = SimpleDataObjectConverter::snakeCaseToUpperCamelCase($propertyName);
-            $methodName = $this->getNameFinder()->getGetterMethodName($class, $camelCaseProperty);
-            $methodReflection = $class->getMethod($methodName);
-            if ($methodReflection->isPublic()) {
-                $returnType = $this->typeProcessor->getGetterReturnType($methodReflection)['type'];
-                try {
-                    $setterName = $this->getNameFinder()->getSetterMethodName($class, $camelCaseProperty);
-                } catch (\Exception $e) {
-                    if (empty($value)) {
-                        continue;
-                    } else {
-                        throw $e;
-                    }
+            try {
+                $methodName = $this->getNameFinder()->getGetterMethodName($class, $camelCaseProperty);
+                if (!isset($this->methodReflectionStorage[$className . $methodName])) {
+                    $this->methodReflectionStorage[$className . $methodName] = $class->getMethod($methodName);
                 }
-                try {
-                    if ($camelCaseProperty === 'CustomAttributes') {
-                        $setterValue = $this->convertCustomAttributeValue($value, $className);
-                    } else {
-                        $setterValue = $this->convertValue($value, $returnType);
+                $methodReflection = $this->methodReflectionStorage[$className . $methodName];
+                if ($methodReflection->isPublic()) {
+                    $returnType = $this->typeProcessor->getGetterReturnType($methodReflection)['type'];
+                    try {
+                        $setterName = $this->getNameFinder()->getSetterMethodName($class, $camelCaseProperty);
+                    } catch (\Exception $e) {
+                        if (empty($value)) {
+                            continue;
+                        } else {
+                            throw $e;
+                        }
                     }
-                } catch (SerializationException $e) {
-                    throw new SerializationException(
-                        new Phrase(
-                            'Error occurred during "%field_name" processing. %details',
-                            ['field_name' => $propertyName, 'details' => $e->getMessage()]
-                        )
-                    );
+                    try {
+                        if ($camelCaseProperty === 'CustomAttributes') {
+                            $setterValue = $this->convertCustomAttributeValue($value, $className);
+                        } else {
+                            $setterValue = $this->convertValue($value, $returnType);
+                        }
+                    } catch (SerializationException $e) {
+                        throw new SerializationException(
+                            new Phrase(
+                                'Error occurred during "%field_name" processing. %details',
+                                ['field_name' => $propertyName, 'details' => $e->getMessage()]
+                            )
+                        );
+                    }
+                    $this->serviceInputValidator->validateEntityValue($object, $propertyName, $setterValue);
+                    $object->{$setterName}($setterValue);
                 }
-                $this->serviceInputValidator->validateEntityValue($object, $propertyName, $setterValue);
-                $object->{$setterName}($setterValue);
+            } catch (\LogicException $e) {
+                $this->processInputErrorForNestedSet([$camelCaseProperty]);
             }
         }
 
@@ -565,4 +579,29 @@ protected function processInputError($inputError)
             }
         }
     }
+
+    /**
+     * Process an input error for child parameters
+     *
+     * @param array $inputError
+     * @return void
+     * @throws InputException
+     */
+    private function processInputErrorForNestedSet(array $inputError): void
+    {
+        if (!empty($inputError)) {
+            $exception = new InputException();
+            foreach ($inputError as $errorParamField) {
+                $exception->addError(
+                    new Phrase(
+                        '"%fieldName" is not supported. Correct the field name and try again.',
+                        ['fieldName' => $errorParamField]
+                    )
+                );
+            }
+            if ($exception->wasErrorAdded()) {
+                throw $exception;
+            }
+        }
+    }
 }
