function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
LeoLiLeoLi 

Access to SObject Schema in Apex is very slow after API v44

We needs to use Schema and DesscribeSObjectResult classes to get all SObject in the user's organization. But we noticed performance problem after upgraded to API v44.
The following code could reproduce the issue:
Visualforce Page Code:
<apex:page controller="TestSchemaTimeController">
    <script type="text/javascript">
        function perform() {
            var args = [];
            var start = new Date().valueOf();
            args.push("{!$RemoteAction.TestSchemaTimeController.QuerySchema}");
            args.push(function(result, event) { var output = document.getElementById("output"); output.value += "Count:" + result + " Time:" + (new Date().valueOf() - start) + "ms\r\n"; });
            args.push({ buffer: false, escape: false, timeout: 120000 }); 
            window.Visualforce.remoting.Manager.invokeAction.apply(window.Visualforce.remoting.Manager, args);
        }
        function clearOutput() {
            var output = document.getElementById("output");
            output.value = "";
        }
    </script>
    <h1>Test Schema Time</h1>
    <div>
        <button onclick="perform()">Click</button>
        <button onclick="clearOutput()">Clear</button>
    </div>
    <div>
        <TextArea id="output" style="width:800px;height:600px"></TextArea>
    </div>
</apex:page>
Apex Code 
public class TestSchemaTimeController {
    @RemoteAction
    public static Integer QuerySchema() {
        Map<String, Schema.SObjectType> typeMap = Schema.getGlobalDescribe();
        for (Schema.SObjectType sot : typeMap.values()) {
            System.debug(sot);
            Schema.DescribeSObjectResult dsr = sot.getDescribe();
            //String name = dsr.getName();
            //Boolean acc = dsr.isAccessible();
        }
        return typeMap.values().size();
    }
}
By the demo code above, it cost about 250~300ms via API version 43, but cost about 1000~1600ms via API version 44. You could modify the API version of the Apex Class to verify the result.
API v45 preview in sandbox also have the performance issue.
We have no idea why this Apex method is slow down after API version 44. And we have to keep on using API version 43 now to make sure our customer not face the performane issue.
Anyone else meet the same problem?
Ken Koellner @ EngagewareKen Koellner @ Engageware
Ever hear anything on this?

Years ago, I noticed some were poor performance with the metadata methods in a org with many custom objects and fields, 500ms for the first call and 250ms for subsequent calls.  A trigger was processing thousands of records and of course, invoked every 200 records.  So the first 200 were delayed by 500ms and each additional batch delayed by 250ms.

Recently we had a custom experiencing poor performance with Schema.getGlobalDescribe();.  I was able to look at debug logs and determine that the response time was 1000-2000ms!  That killed processing as the result it not cached and it got called a dozen times from several different classes.  I do not have the ability to get into that org and run a prior API version.

The problem could be measured with the following anoymous Apex.  I tried it in our org which doesn't have a lot of custom metadata.  I get 100-200ms response time regardless of what API version I used.  I tried 50.0 all the way back to 36.0.
 
Long beforeTime = System.now().gettime();
Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();
Long afterTime = System.now().gettime();
Long runTIme = afterTime-beforeTime;
System.debug('Runtime -- ' + runTime + '(ms)');