WebCenter Sites 12c Performance with Asset Reader API and Groovy
package oracle.webcenter.sites.controller import com.fatwire.assetapi.data.* import com.openmarket.xcelerate.asset.* import com.fatwire.assetapi.fragment.* import com.fatwire.system.* import org.slf4j.Logger import org.slf4j.LoggerFactory import java.util.List import java.util.ArrayList import COM.FutureTense.Interfaces.* import com.fatwire.cs.core.db.PreparedStmt import com.fatwire.cs.core.db.StatementParam import COM.FutureTense.Util.IterableIListWrapper import com.fatwire.assetapi.common.AssetAccessException public class ArticlePageController extends BaseController { static final private Logger log = LoggerFactory.getLogger("oracle.wcsites.test.article") @RequiredParams(query="c,cid") public void doWork(Map models) { log.debug("Article Page Loading...") runArticleTest() } public AssetId findArticleByName(String name) throws AssetAccessException { AssetId result = null PreparedStmt stmt = new PreparedStmt("select id from AVIArticle where name like ?", Arrays.asList("AVIArticle")) stmt.setElement(0, "AVIArticle", "id") StatementParam param = stmt.newParam() param.setString(0, "%" + name + "%") IList records = ics.SQL(stmt, param, false) for (IList record : new IterableIListWrapper(records)){ long id = Long.parseLong(record.getValue("id")) result = new AssetIdImpl("AVIArticle", id) } return result } public void runArticleTest(){ // read in avisports articles for test log.debug("Initializing") long startTime long endTime Session wcsession = SessionFactory.getSession(); AssetDataManager adm = (AssetDataManager)wcsession.getManager(AssetDataManager.class.getName()) AssetId testArticle1 = findArticleByName("Veteran Skier Says Goodbye") List<AssetId> assetsToGet = new ArrayList<AssetId>() assetsToGet.add(testArticle1) log.debug("test 1 - reading asset") startTime = System.nanoTime() adm.read(assetsToGet) endTime = System.nanoTime() log.debug("test 1 completion time: " + String.valueOf((endTime-startTime) / 1000000 )) ics.StreamEvalBytes("test 1 completion time: " + String.valueOf((endTime-startTime) / 1000000 )) // second test read just the fields we need from an asset AssetId testArticle2 = findArticleByName("Skier Makes Her Mark") log.debug("test 2 - reading specific fields") startTime = System.nanoTime() adm.readAttributes(testArticle2, Arrays.asList("name", "body")) endTime = System.nanoTime() log.debug("test 2 completion time: " + String.valueOf((endTime-startTime) / 1000000)) ics.StreamEvalBytes("<br>test 2 completion time: " + String.valueOf((endTime-startTime) / 1000000)) // third test, read using selectAll AssetId testArticle3 = findArticleByName("25 Nevada Resorts Serving Snow") log.debug("test 3 - reading asset new api") startTime = System.nanoTime() newAssetReader().forAsset(testArticle3).selectAll(true).read() endTime = System.nanoTime() log.debug("test 3 completion time: " + String.valueOf((endTime-startTime) / 1000000)) ics.StreamEvalBytes("<br>test 3 completion time: " + String.valueOf((endTime-startTime) / 1000000)) // fourth test, read using select specific fields AssetId testArticle4 = findArticleByName("Ski Castle and Snowboard Wizards Unite") log.debug("test 4 - reading specific fields new api") startTime = System.nanoTime() newAssetReader().forAsset(testArticle4).select("name,body").read() endTime = System.nanoTime() log.debug("test 4 completion time: " + String.valueOf((endTime-startTime) / 1000000)) ics.StreamEvalBytes("<br>test 4 completion time: " + String.valueOf((endTime-startTime) / 1000000)) } }
<%@ taglib prefix="cs" uri="futuretense_cs/ftcs1_0.tld" %><%@ taglib prefix="ics" uri="futuretense_cs/ics.tld" %><%@ taglib prefix="render" uri="futuretense_cs/render.tld" %><%@ taglib prefix="fragment" uri="futuretense_cs/fragment.tld" %><%@ page import="com.fatwire.assetapi.data.*, com.openmarket.xcelerate.asset.*, com.fatwire.assetapi.fragment.*, com.fatwire.system.*, org.slf4j.Logger, org.slf4j.LoggerFactory, java.util.List, java.util.ArrayList, COM.FutureTense.Interfaces.*, com.fatwire.cs.core.db.PreparedStmt, com.fatwire.cs.core.db.StatementParam, COM.FutureTense.Util.IterableIListWrapper, com.fatwire.assetapi.common.AssetAccessException, java.util.Arrays" %><cs:ftcs><%-- Page/PerformanceTest2 --%> <%-- Record dependencies for the Template --%> <ics:if condition='<%=ics.GetVar("tid")!=null%>'><ics:then><render:logdep cid='<%=ics.GetVar("tid")%>' c="Template"/></ics:then></ics:if> <%! static final private Logger log = LoggerFactory.getLogger("oracle.wcsites.test.article"); private BuildersFactory builder; public AssetId findArticleByName(ICS ics, String name) throws AssetAccessException, NoSuchFieldException { AssetId result = null; PreparedStmt stmt = new PreparedStmt("select id from AVIArticle where name like ?", Arrays.asList("AVIArticle")); stmt.setElement(0, "AVIArticle", "id"); StatementParam param = stmt.newParam(); param.setString(0, "%" + name + "%"); IList records = ics.SQL(stmt, param, false); for (IList record : new IterableIListWrapper(records)){ long id = Long.parseLong(record.getValue("id")); result = new AssetIdImpl("AVIArticle", id); } return result; } public void runArticleTest(ICS ics, BuildersFactory builer) throws AssetAccessException, NoSuchFieldException{ // read in avisports articles for test log.debug("Initializing"); long startTime; long endTime; Session wcsession = SessionFactory.getSession(); AssetDataManager adm = (AssetDataManager)wcsession.getManager(AssetDataManager.class.getName()); AssetId testArticle1 = findArticleByName(ics, "Veteran Skier Says Goodbye"); List<AssetId> assetsToGet = new ArrayList<AssetId>(); assetsToGet.add(testArticle1); log.debug("test 1 - reading asset"); startTime = System.nanoTime(); adm.read(assetsToGet); endTime = System.nanoTime(); log.debug("test 1 completion time: " + String.valueOf((endTime-startTime) / 1000000 )); ics.StreamEvalBytes("test 1 completion time: " + String.valueOf((endTime-startTime) / 1000000 )); // second test read just the fields we need from an asset AssetId testArticle2 = findArticleByName(ics, "Skier Makes Her Mark"); log.debug("test 2 - reading specific fields"); startTime = System.nanoTime(); adm.readAttributes(testArticle2, Arrays.asList("name", "body")); endTime = System.nanoTime(); log.debug("test 2 completion time: " + String.valueOf((endTime-startTime) / 1000000)); ics.StreamEvalBytes("<br>test 2 completion time: " + String.valueOf((endTime-startTime) / 1000000)); // third test, read using selectAll AssetId testArticle3 = findArticleByName(ics, "25 Nevada Resorts Serving Snow"); log.debug("test 3 - reading asset new api"); startTime = System.nanoTime(); builder.newAssetReader().forAsset(testArticle3).selectAll(true).read(); endTime = System.nanoTime(); log.debug("test 3 completion time: " + String.valueOf((endTime-startTime) / 1000000)); ics.StreamEvalBytes("<br>test 3 completion time: " + String.valueOf((endTime-startTime) / 1000000)); // fourth test, read using select specific fields AssetId testArticle4 = findArticleByName(ics, "Ski Castle and Snowboard Wizards Unite"); log.debug("test 4 - reading specific fields new api"); startTime = System.nanoTime(); builder.newAssetReader().forAsset(testArticle4).select("name,body").read(); endTime = System.nanoTime(); log.debug("test 4 completion time: " + String.valueOf((endTime-startTime) / 1000000)); ics.StreamEvalBytes("<br>test 4 completion time: " + String.valueOf((endTime-startTime) / 1000000)); } %> <% try { builder = new DefaultBuildersFactory(ics); runArticleTest(ics, builder); } catch(Exception ex){ log.error("error running tests"); } %> </cs:ftcs>
<%@ taglib prefix="cs" uri="futuretense_cs/ftcs1_0.tld"
%><%@ taglib prefix="ics" uri="futuretense_cs/ics.tld"
%><%@ taglib prefix="render" uri="futuretense_cs/render.tld"
%><%@ taglib prefix="fragment" uri="futuretense_cs/fragment.tld"
%><cs:ftcs><%-- Page/PerformanceTest3 --%>
<%-- Record dependencies for the Template --%>
<ics:if condition='<%=ics.GetVar("tid")!=null%>'><ics:then><render:logdep cid='<%=ics.GetVar("tid")%>' c="Template"/></ics:then></ics:if>
<%
long startTime = System.nanoTime();
%>
<ics:callelement element="PerformanceTest/JSPTest"></ics:callelement>
<%
long endTime = System.nanoTime();
ics.StreamEvalBytes("<br>completion time: " + String.valueOf((endTime-startTime) / 1000000));
%>
</cs:ftcs>
import com.fatwire.assetapi.data.*
import com.openmarket.xcelerate.asset.*
import com.fatwire.assetapi.fragment.*
import com.fatwire.system.*
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import java.util.List
import java.util.ArrayList
import COM.FutureTense.Interfaces.*
import com.fatwire.cs.core.db.PreparedStmt
import com.fatwire.cs.core.db.StatementParam
import COM.FutureTense.Util.IterableIListWrapper
import com.fatwire.assetapi.common.AssetAccessException
import java.util.Arrays
new PerformanceTest(ics)
public class PerformanceTest {
Logger log = LoggerFactory.getLogger("oracle.wcsites.test.article");
BuildersFactory builder;
AssetId findArticleByName(ICS ics, String name) throws AssetAccessException, NoSuchFieldException {
AssetId result = null;
PreparedStmt stmt = new PreparedStmt("select id from AVIArticle where name like ?", Arrays.asList("AVIArticle"));
stmt.setElement(0, "AVIArticle", "id");
StatementParam param = stmt.newParam();
param.setString(0, "%" + name + "%");
IList records = ics.SQL(stmt, param, false);
for (IList record : new IterableIListWrapper(records)){
long id = Long.parseLong(record.getValue("id"));
result = new AssetIdImpl("AVIArticle", id);
}
return result;
}
void runArticleTest(ICS ics, BuildersFactory builer) throws AssetAccessException, NoSuchFieldException{
log.debug("running groovy tests")
// read in avisports articles for test
log.debug("Initializing");
long startTime;
long endTime;
Session wcsession = SessionFactory.getSession();
AssetDataManager adm = (AssetDataManager)wcsession.getManager(AssetDataManager.class.getName());
AssetId testArticle1 = findArticleByName(ics, "Veteran Skier Says Goodbye");
List<AssetId> assetsToGet = new ArrayList<AssetId>();
assetsToGet.add(testArticle1);
log.debug("test 1 - reading asset");
startTime = System.nanoTime();
adm.read(assetsToGet);
endTime = System.nanoTime();
log.debug("test 1 completion time: " + String.valueOf((endTime-startTime) / 1000000 ));
ics.StreamEvalBytes("test 1 completion time: " + String.valueOf((endTime-startTime) / 1000000 ));
// second test read just the fields we need from an asset
AssetId testArticle2 = findArticleByName(ics, "Skier Makes Her Mark");
log.debug("test 2 - reading specific fields");
startTime = System.nanoTime();
adm.readAttributes(testArticle2, Arrays.asList("name", "body"));
endTime = System.nanoTime();
log.debug("test 2 completion time: " + String.valueOf((endTime-startTime) / 1000000));
ics.StreamEvalBytes("<br>test 2 completion time: " + String.valueOf((endTime-startTime) / 1000000));
// third test, read using selectAll
AssetId testArticle3 = findArticleByName(ics, "25 Nevada Resorts Serving Snow");
log.debug("test 3 - reading asset new api");
startTime = System.nanoTime();
builder.newAssetReader().forAsset(testArticle3).selectAll(true).read();
endTime = System.nanoTime();
log.debug("test 3 completion time: " + String.valueOf((endTime-startTime) / 1000000));
ics.StreamEvalBytes("<br>test 3 completion time: " + String.valueOf((endTime-startTime) / 1000000));
// fourth test, read using select specific fields
AssetId testArticle4 = findArticleByName(ics, "Ski Castle and Snowboard Wizards Unite");
log.debug("test 4 - reading specific fields new api");
startTime = System.nanoTime();
builder.newAssetReader().forAsset(testArticle4).select("name,body").read();
endTime = System.nanoTime();
log.debug("test 4 completion time: " + String.valueOf((endTime-startTime) / 1000000));
ics.StreamEvalBytes("<br>test 4 completion time: " + String.valueOf((endTime-startTime) / 1000000));
}
public PerformanceTest(ICS ics){
try {
builder = new DefaultBuildersFactory(ics);
runArticleTest(ics, builder);
} catch(Exception ex){
log.error("error running tests");
log.error(ex.getMessage())
log.error(Arrays.toString(Thread.currentThread().getStackTrace()))
}
}
}
<%@ taglib prefix="cs" uri="futuretense_cs/ftcs1_0.tld" %><%@ taglib prefix="ics" uri="futuretense_cs/ics.tld" %><%@ page import="com.fatwire.assetapi.data.*, com.openmarket.xcelerate.asset.*, com.fatwire.assetapi.fragment.*, com.fatwire.system.*, org.slf4j.Logger, org.slf4j.LoggerFactory, java.util.List, java.util.ArrayList, COM.FutureTense.Interfaces.*, com.fatwire.cs.core.db.PreparedStmt, com.fatwire.cs.core.db.StatementParam, COM.FutureTense.Util.IterableIListWrapper, com.fatwire.assetapi.common.AssetAccessException, java.util.Arrays" %><cs:ftcs> <%! static final private Logger log = LoggerFactory.getLogger("oracle.wcsites.test.article"); private BuildersFactory builder; public AssetId findArticleByName(ICS ics, String name) throws AssetAccessException, NoSuchFieldException { AssetId result = null; PreparedStmt stmt = new PreparedStmt("select id from AVIArticle where name like ?", Arrays.asList("AVIArticle")); stmt.setElement(0, "AVIArticle", "id"); StatementParam param = stmt.newParam(); param.setString(0, "%" + name + "%"); IList records = ics.SQL(stmt, param, false); for (IList record : new IterableIListWrapper(records)){ long id = Long.parseLong(record.getValue("id")); result = new AssetIdImpl("AVIArticle", id); } return result; } public void runArticleTest(ICS ics, BuildersFactory builer) throws AssetAccessException, NoSuchFieldException{ // read in avisports articles for test log.debug("Initializing"); long startTime; long endTime; Session wcsession = SessionFactory.getSession(); AssetDataManager adm = (AssetDataManager)wcsession.getManager(AssetDataManager.class.getName()); AssetId testArticle1 = findArticleByName(ics, "Veteran Skier Says Goodbye"); List<AssetId> assetsToGet = new ArrayList<AssetId>(); assetsToGet.add(testArticle1); log.debug("test 1 - reading asset"); startTime = System.nanoTime(); adm.read(assetsToGet); endTime = System.nanoTime(); log.debug("test 1 completion time: " + String.valueOf((endTime-startTime) / 1000000 )); ics.StreamEvalBytes("test 1 completion time: " + String.valueOf((endTime-startTime) / 1000000 )); // second test read just the fields we need from an asset AssetId testArticle2 = findArticleByName(ics, "Skier Makes Her Mark"); log.debug("test 2 - reading specific fields"); startTime = System.nanoTime(); adm.readAttributes(testArticle2, Arrays.asList("name", "body")); endTime = System.nanoTime(); log.debug("test 2 completion time: " + String.valueOf((endTime-startTime) / 1000000)); ics.StreamEvalBytes("<br>test 2 completion time: " + String.valueOf((endTime-startTime) / 1000000)); // third test, read using selectAll AssetId testArticle3 = findArticleByName(ics, "25 Nevada Resorts Serving Snow"); log.debug("test 3 - reading asset new api"); startTime = System.nanoTime(); builder.newAssetReader().forAsset(testArticle3).selectAll(true).read(); endTime = System.nanoTime(); log.debug("test 3 completion time: " + String.valueOf((endTime-startTime) / 1000000)); ics.StreamEvalBytes("<br>test 3 completion time: " + String.valueOf((endTime-startTime) / 1000000)); // fourth test, read using select specific fields AssetId testArticle4 = findArticleByName(ics, "Ski Castle and Snowboard Wizards Unite"); log.debug("test 4 - reading specific fields new api"); startTime = System.nanoTime(); builder.newAssetReader().forAsset(testArticle4).select("name,body").read(); endTime = System.nanoTime(); log.debug("test 4 completion time: " + String.valueOf((endTime-startTime) / 1000000)); ics.StreamEvalBytes("<br>test 4 completion time: " + String.valueOf((endTime-startTime) / 1000000)); } %> <% try { builder = new DefaultBuildersFactory(ics); runArticleTest(ics, builder); } catch(Exception ex){ log.error("error running tests"); } %> </cs:ftcs>
Conclusion
Based on what I found doing these tests it appears there is no real difference in performance between creating elements in groovy instead of using java in JSPs. That is a significant improvement over the performance of groovy elements over 11g. The new asset reader API does appear to be quite a bit slower than using the older AssetDataManager from 11g but it has some benefits. It does reduce the amount of code needed to interact with your assets and the data returned can be put into the model in the MVC framework rather than having to be manipulated or transformed first. In fact some of the differences in performance may be made up for depending on what needs to be done with the asset data after being loaded using the AssetDataManager. The best API to use may not be the same in every situation but it does appear that the older 11g API may be needed if your page isn't performing fast enough under the new ones from 12c.
- Log in to post comments