wiki:MapGuideRfc110

MapGuide RFC 110 - Profiling API enhancement

This page contains a change request (RFC) for the MapGuide Open Source project. More MapGuide RFCs can be found on the RFCs page.

Status

RFC Template Version(1.0)
Submission Date February 23,2011
Last Modified Bruce Dechant, June 5,2011
Author Bruce Dechant, Ted Yang, Arthur Liu
RFC Status ready for review
Implementation Status(under development)
Proposed Milestone 2.3
Assigned PSC guide(s)Bruce Dechant
Voting HistoryBruce Dechant, Jackie Ng, Zac Spitzer, Trevor Wekel, Tom Fukushima, Haris Kurtagic
+1
+0
-0
-1
no vote

Overview

This RFC adds a MgProfilingService which provides a skeleton for developers to profile existing MapGuide APIs. MgProfilingService aims to help developers and end users to identify resources that need to be optimized and performance bottlenecks. Two Profiling APIs will be implemented in this RFC and developers can add their own Profiling API into MgProfilingService in the future. Also we will implement a UI in Site Admin to help the administrators easily execute a profiling and analyze the result.

Motivation

Profiling APIs that would generate an XML report that could be analyzed to help determine if any resources need to be optimized or if there are performance bottlenecks in the code that need to be looked at. And The UI will offer an visual way to perform the profiling and review the result.

Proposed Solution

The following NEW APIs will be added to the offical API (PHP, Java and .Net):

MgByteReader* ProfileRenderMap(MgMap* map,
                               MgSelection* selection,
                               MgCoordinate* center,
                               double scale,
                               INT32 width,
                               INT32 height,
                               MgColor* backgroundColor,
                               CREFSTRING format,
                               bool bKeepSelection);
MgByteReader* ProfileRenderDynamicOverlay(MgMap* map,
                                          MgSelection* selection,
                                          MgRenderingOptions* options);

Both of the above APIs will return an XML document that contains the profiling information gathered. The UI will be implemented in Site Admin as a php web page. There will be input fields for the required parameters of a profiling. The parameters can also be encoded into the URL so that the profiling UI could be easily integrated with some custom application of MapGuide. After a profiling has finished with the input parameters, the result XML document will be returned and parsed. Then the webpage will show the total render time for the map, and the render time of each layer in the map. Some additional layer information will be also showed to help the user analyze the results.The result could be exported as .csv file so that the user could do further analysis with other applications like Microsoft Excel.

(We are not going to implement the Http API for MgProfilingService)

Information Gathered

The profiling information gathered for ProfileRenderMap and ProfileRenderDynamicOverlay:

ProfileRenderMap:

Resource Id
Coordinate System
Extent
Scale
Image Format
Render Map Time
Render Layers Time
Render Selection Time
Render Watermars Time
Render Labels Time
Create Image Time

ProfileRenderLayer:

Resource Id
Layer Type
Coordinate System
Current Scale Range
Filter
Render Time

ProfileRenderWatermark:

Resource Id
Position Type
Stylization Time

ProfileRenderLabels:

Render Labels Time

XML Report / Schema

The generated XML report document will be defined by the following schema.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0.0">
  <xs:include schemaLocation="PlatformCommon-1.0.0.xsd"/>
  <xs:element name="ProfileResult" type="ProfileResultType"></xs:element>
  <xs:complexType name="ProfileResultType">
    <xs:choice>
      <xs:element name="ProfileRenderMap" type="ProfilerRenderMapType">
      </xs:element>
      <xs:element name="ProfileRenderDynamicOverlay" type="ProfilerRenderMapType">
      </xs:element>
      <xs:element name="ExtendedData1" type="ExtendedDataType" minOccurs="0"/>
    </xs:choice>
  </xs:complexType>
  <xs:complexType name="ProfilerRenderMapType">
    <xs:sequence>
      <xs:element name="ResourceId" type="xs:string"></xs:element>
      <xs:element name="CoordinateSystem" type="xs:string"></xs:element>
      <xs:element name="Extent" type="xs:string"></xs:element>
      <xs:element name="Scale" type="xs:double"></xs:element>
      <xs:element name="ImageFormat" type="xs:string"></xs:element>
      <xs:element name="RendererType" type="xs:string"></xs:element>
      <xs:element name="RenderTime" type="xs:double"></xs:element>
      <xs:element name="ProfileRenderLayers" type="ProfileRenderLayersType"></xs:element>
      <xs:element name="ProfileRenderSelection" type="ProfileRenderSelectionType"></xs:element>
      <xs:element name="ProfileRenderWatermarks" type="ProfileRenderWatermarksType"></xs:element>
      <xs:element name="ProfileRenderLabels" type="ProfileRenderLabelsType"></xs:element>
      <xs:element name="CreateImageTime" type="xs:double"></xs:element>
      <xs:element name="ExtendedData1" type="ExtendedDataType" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ProfileRenderLayersType">
    <xs:sequence>
      <xs:element name="RenderTime" type="xs:double"></xs:element>
      <xs:element name="ProfileRenderLayer" type="ProfileRenderLayerType" minOccurs="0" maxOccurs="unbounded"></xs:element>
      <xs:element name="ExtendedData1" type="ExtendedDataType" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ProfileRenderSelectionType">
    <xs:sequence>
      <xs:element name="RenderTime" type="xs:double"></xs:element>
      <xs:element name="Filter" type="xs:string"></xs:element>
      <xs:element name="ProfileRenderSelectedLayer" type="ProfileRenderLayerType" minOccurs="0" maxOccurs="unbounded"></xs:element>
      <xs:element name="ExtendedData1" type="ExtendedDataType" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ProfileRenderWatermarksType">
    <xs:sequence>
      <xs:element name="RenderTime" type="xs:double"></xs:element>
      <xs:element name="ProfileRenderWatermark" type="ProfileRenderWatermarkType" minOccurs="0" maxOccurs="unbounded"></xs:element>
      <xs:element name="ExtendedData1" type="ExtendedDataType" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ProfileRenderLabelsType">
    <xs:sequence>
      <xs:element name="RenderTime" type="xs:double"></xs:element>
      <xs:element name="ExtendedData1" type="ExtendedDataType" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ProfileRenderLayerType">
    <xs:sequence>
      <xs:element name="ResourceId" type="xs:string"></xs:element>
      <xs:element name="LayerType" type="xs:string"></xs:element>
      <xs:element name="CoordinateSystem" type="xs:string"></xs:element>
      <xs:element name="ScaleRange" type="xs:string"></xs:element>
      <xs:element name="Filter" type="xs:string"></xs:element>
      <xs:element name="RenderTime" type="xs:double"></xs:element>
      <xs:element name="ExtendedData1" type="ExtendedDataType" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ProfileRenderWatermarkType">
    <xs:sequence>
      <xs:element name="ResourceId" type="xs:string"></xs:element>
      <xs:element name="PositionType" type="xs:string"></xs:element>
      <xs:element name="RenderTime" type="xs:double"></xs:element>
      <xs:element name="ExtendedData1" type="ExtendedDataType" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

Example of profiling rendering map process:

<?xml version="1.0" encoding="utf-8"?>
<ProfileResult>
  <ProfileRenderMap>
    <ResourceId>Library://Shaboygan.MapDefinition</ResourceId>
    <CoordinateSystem>LL84</CoordinateSystem>
    <Extent>43.73,-87.73,43.75,-87.72</Extent>
    <Scale>10000.00</Scale>
    <ImageFormat>PNG</ImageFormat>
    <RendererType>AGG</RendererType>
    <RenderTime>8.30</RenderTime>
    <ProfileRenderLayers>
      <RenderTime>5.00</RenderTime>
      <ProfileRenderLayer>
        <ResourceId>Library://Buildings.LayerDefinition</ResourceId>
        <LayerType>Vector</LayerType>
        <CoordinateSystem>CA-I</CoordinateSystem>
        <ScaleRange>ScaleRange1</ScaleRange>
        <Filter>FeatId &gt; 5</Filter>
        <RenderTime>3.00</RenderTime>
      </ProfileRenderLayer>
      <ProfileRenderLayer>
        <ResourceId>Library://Districts.LayerDefinition</ResourceId>
        <LayerType>Raster</LayerType>
        <CoordinateSystem>LL84</CoordinateSystem>
        <ScaleRange>ScaleRange2</ScaleRange>
        <Filter></Filter>
        <RenderTime>2.00</RenderTime>
      </ProfileRenderLayer>
    </ProfileRenderLayers>
    <ProfileRenderSelection>
      <RenderTime>0.25</RenderTime>
      <Filter>FeatId &lt; 100</Filter>
      <ProfileRenderSelectedLayer>
        <ResourceId>Library://Trees.LayerDefinition</ResourceId>
        <LayerType>Vector</LayerType>
        <CoordinateSystem>LL84</CoordinateSystem>
        <ScaleRange>ScaleRange1</ScaleRange>
        <Filter>FeatId &lt; 200</Filter>
        <RenderTime>0.10</RenderTime>
      </ProfileRenderSelectedLayer>
      <ProfileRenderSelectedLayer>
        <ResourceId>Library://Parcels.LayerDefinition</ResourceId>
        <LayerType>Vector</LayerType>
        <CoordinateSystem>LL84</CoordinateSystem>
        <ScaleRange>ScaleRange2</ScaleRange>
        <Filter></Filter>
        <RenderTime>0.15</RenderTime>
      </ProfileRenderSelectedLayer>
    </ProfileRenderSelection>
    <ProfileRenderWatermarks>
      <RenderTime>0.75</RenderTime>
      <ProfileRenderWatermark>
        <ResourceId>Library://Logo.WatermarkDefinition</ResourceId>
        <PositionType>Tile</PositionType>
        <RenderTime>0.6</RenderTime>
      </ProfileRenderWatermark>
      <ProfileRenderWatermark>
        <ResourceId>Library://Copyright.WatermarkDefinition</ResourceId>
        <PositionType>XY</PositionType>
        <RenderTime>0.15</RenderTime>
      </ProfileRenderWatermark>
    </ProfileRenderWatermarks>
    <ProfileRenderLabels>
      <RenderTime>1.25</RenderTime>
    </ProfileRenderLabels>
    <CreateImageTime>1</CreateImageTime>
  </ProfileRenderMap>
</ProfileResult>

Implications

To profile an existing MapGuide API, the profiling code will be injected into the original functions being profiled, which means MgServerServices should be extended to accept a MgProfileResult and the implementation of some APIs will be updated to support profiling. For example, to support profiling RenderMap, MgRenderingServerService needs to be extented by inheriting from MgProfileManager which provides set/get method for MgProfileResult.

The injected code will be executed only when the original code being invoked by ProfilingService, so the the only impact to the original methods will be the extra if/else processing and nothing more.

Test Plan

Build/Run on Windows/Linux

Funding / Resources

Supplied by Autodesk

Last modified 6 years ago Last modified on Jul 18, 2011 6:53:28 PM

Attachments (2)

Download all attachments as: .zip