我为这篇文章的长度道歉。我试图使这个缓慢的规则问题可重现。
我正在使用 TopBraid Composer FE 创建一个带有本体和 SPIN 构造函数的 RDF 文件。SPIN 构造函数的目的是检查本体中定义的类的个体实例化的合规性。我发现 SPIN 构造函数的执行速度很慢,我想知道为什么。
包括 SPIN 构造函数的本体 SXXIComplianceCheck18.rdf
我修改/清除我的存储库(一个支持 RDFS+SPIN 的内存存储)并将这个本体加载到 RDF4J 工作台中:
接下来,我依次使用两个 SPARQL 更新查询来创建本体(上面的 RDF 文件)中定义的类的个体,从而刺激运行 SPIN 构造函数。
第一个 SPARQL 更新查询(实例化单个数据项并根据需要调用解析构造函数......运行速度很快):
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX sxxicc: <http://www.disa.mil/dso/a2i/ontologies/PBSM/Interface/SXXIComplianceCheck#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX sp: <http://spinrdf.org/sp#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX smf: <http://topbraid.org/sparqlmotionfunctions#>
PREFIX fn: <http://www.w3.org/2005/xpath-functions#>
PREFIX spl: <http://spinrdf.org/spl#>
PREFIX spin: <http://spinrdf.org/spin#>
PREFIX arg: <http://spinrdf.org/arg#>
PREFIX SXXIComplianceCheckIndividuals: <http://www.disa.mil/dso/a2i/ontologies/PBSM/Interface/SXXIComplianceCheckIndividuals#>
PREFIX sxxicci: <http://www.disa.mil/dso/a2i/ontologies/PBSM/Interface/SXXIComplianceCheckIndividuals#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
INSERT DATA
{
sxxicci:testPub7Proposal_DataItem110 a sxxicc:Pub7DataItem110 ;
sxxicc:pub7DataItemHasRawStringValue "(C) M221.5"^^xsd:string .
sxxicci:testPub7Proposal_DataItem500 a sxxicc:Pub7DataItem500 ;
sxxicc:pub7DataItemHasRawStringValue "S181"^^xsd:string .
sxxicci:testPub7Proposal_DataItem300 a sxxicc:Pub7DataItem300 ;
sxxicc:pub7DataItemHasRawStringValue "DC"^^xsd:string .
sxxicci:testPub7Proposal_DataItem113 a sxxicc:Pub7DataItem113 ;
sxxicc:pub7DataItemHasRawStringValue "FX"^^xsd:string .
sxxicci:testPub7Proposal_DataItem511 a sxxicc:Pub7DataItem511 ;
sxxicc:pub7DataItemHasRawStringValue "SIGHT SEEING"^^xsd:string .
sxxicci:testPub7Proposal_DataItem501 a sxxicc:Pub7DataItem501 ;
# sxxicc:pub7DataItemHasRawStringValue "M002"^^xsd:string .
sxxicc:pub7DataItemHasRawStringValue "M018, 160727"^^xsd:string .
sxxicci:testPub7Proposal_DataItem503 a sxxicc:Pub7DataItem503 ;
sxxicc:pub7DataItemHasRawStringValue "CUBESAT, TOM"^^xsd:string .
sxxicci:testPub7Proposal_DataItem504a a sxxicc:Pub7DataItem504 ;
sxxicc:pub7DataItemHasRawStringValue "FAS Agenda line 1"^^xsd:string ;
sxxicc:pub7DataItemHasOrdinalNumber "1"^^xsd:integer .
sxxicci:testPub7Proposal_DataItem504b a sxxicc:Pub7DataItem504 ;
sxxicc:pub7DataItemHasRawStringValue "FAS Agenda line 2"^^xsd:string ;
sxxicc:pub7DataItemHasOrdinalNumber "2"^^xsd:integer .
sxxicci:testPub7Proposal_DataItem504c a sxxicc:Pub7DataItem504 ;
sxxicc:pub7DataItemHasRawStringValue "FAS Agenda line 3"^^xsd:string ;
sxxicc:pub7DataItemHasOrdinalNumber "3"^^xsd:integer .
sxxicci:testPub7Proposal_DataItem504d a sxxicc:Pub7DataItem504 ;
sxxicc:pub7DataItemHasRawStringValue "FAS Agenda line 4"^^xsd:string ;
sxxicc:pub7DataItemHasOrdinalNumber "4"^^xsd:integer .
sxxicci:testPub7Proposal_DataItem504e a sxxicc:Pub7DataItem504 ;
sxxicc:pub7DataItemHasRawStringValue "FAS Agenda line 5"^^xsd:string ;
sxxicc:pub7DataItemHasOrdinalNumber "5"^^xsd:integer .
sxxicci:testPub7Proposal_DataItem504f a sxxicc:Pub7DataItem504 ;
sxxicc:pub7DataItemHasRawStringValue "FAS Agenda line 6"^^xsd:string ;
sxxicc:pub7DataItemHasOrdinalNumber "6"^^xsd:integer .
sxxicci:testPub7Proposal_DataItem144 a sxxicc:Pub7DataItem144 ;
sxxicc:pub7DataItemHasRawStringValue "Y"^^xsd:string .
sxxicci:testPub7Proposal_DataItem005 a sxxicc:Pub7DataItem005 ;
sxxicc:pub7DataItemHasRawStringValue "SF"^^xsd:string .
sxxicci:testPub7Proposal_DataItem102 a sxxicc:Pub7DataItem102 ;
sxxicc:pub7DataItemHasRawStringValue "S 881234"^^xsd:string .
sxxicci:testPub7Proposal_DataItem017 a sxxicc:Pub7DataItem017 ;
sxxicc:pub7DataItemHasRawStringValue "C"^^xsd:string .
}
第二个 SPARQL 更新查询(实例化将第一个查询实例化的数据项联系在一起并运行合规性检查构造函数的提案......在我的计算机上运行非常缓慢,大约 20 秒):
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX sxxicc: <http://www.disa.mil/dso/a2i/ontologies/PBSM/Interface/SXXIComplianceCheck#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX sp: <http://spinrdf.org/sp#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX smf: <http://topbraid.org/sparqlmotionfunctions#>
PREFIX fn: <http://www.w3.org/2005/xpath-functions#>
PREFIX spl: <http://spinrdf.org/spl#>
PREFIX spin: <http://spinrdf.org/spin#>
PREFIX arg: <http://spinrdf.org/arg#>
PREFIX SXXIComplianceCheckIndividuals: <http://www.disa.mil/dso/a2i/ontologies/PBSM/Interface/SXXIComplianceCheckIndividuals#>
PREFIX sxxicci: <http://www.disa.mil/dso/a2i/ontologies/PBSM/Interface/SXXIComplianceCheckIndividuals#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
INSERT DATA
{
sxxicci:TestPub7Proposal a sxxicc:Pub7Proposal ;
sxxicc:pub7ProposalHasDataItem sxxicci:testPub7Proposal_DataItem005 ;
sxxicc:pub7ProposalHasDataItem sxxicci:testPub7Proposal_DataItem017 ;
sxxicc:pub7ProposalHasDataItem sxxicci:testPub7Proposal_DataItem102 ;
sxxicc:pub7ProposalHasDataItem sxxicci:testPub7Proposal_DataItem110 ;
sxxicc:pub7ProposalHasDataItem sxxicci:testPub7Proposal_DataItem113 ;
sxxicc:pub7ProposalHasDataItem sxxicci:testPub7Proposal_DataItem144 ;
sxxicc:pub7ProposalHasDataItem sxxicci:testPub7Proposal_DataItem300 ;
sxxicc:pub7ProposalHasDataItem sxxicci:testPub7Proposal_DataItem500 ;
sxxicc:pub7ProposalHasDataItem sxxicci:testPub7Proposal_DataItem501 ;
sxxicc:pub7ProposalHasDataItem sxxicci:testPub7Proposal_DataItem503 ;
sxxicc:pub7ProposalHasDataItem sxxicci:testPub7Proposal_DataItem504a ;
sxxicc:pub7ProposalHasDataItem sxxicci:testPub7Proposal_DataItem504b ;
sxxicc:pub7ProposalHasDataItem sxxicci:testPub7Proposal_DataItem504c ;
sxxicc:pub7ProposalHasDataItem sxxicci:testPub7Proposal_DataItem504d ;
sxxicc:pub7ProposalHasDataItem sxxicci:testPub7Proposal_DataItem504e ;
# sxxicc:pub7ProposalHasDataItem sxxicci:testPub7Proposal_DataItem504f ;
sxxicc:pub7ProposalHasDataItem sxxicci:testPub7Proposal_DataItem511 .
}
第二个查询需要很长时间才能执行,大约 20 秒。这与其他合规性检查(未包含在此 RDF 中)不一致。我已将这条规则从其他 13 条类似规则(主要是字符串解析和比较)中分离出来,因为它支配了时间消耗。
(正确但延迟的)结果:
有问题的 SPIN 构造函数(用于sxxicc:Pub7Proposal
类):
# NEED MINUTE <M> NOTE M002 IN CIRCUIT REMARKS LISTING IRAC DOCUMENT GIVING APPROVAL FOR THIS ASSIGNMENT. (501 08)
CONSTRUCT {
?this sxxicc:pub7ProposalHasComplianceMessage "NEED MINUTE <M> NOTE M002 IN CIRCUIT REMARKS LISTING IRAC DOCUMENT GIVING APPROVAL FOR THIS ASSIGNMENT. (501 08)"^^xsd:string .
}
WHERE {
?this a sxxicc:Pub7Proposal .
?this sxxicc:pub7ProposalHasDataItem ?dataItem102 .
?dataItem102 a sxxicc:Pub7DataItem102 .
?dataItem102 sxxicc:pub7DataItemHasStringValue ?serialNumString .
?this sxxicc:pub7ProposalHasDataItem ?dataItem500 .
?dataItem500 a sxxicc:Pub7DataItem500 .
?dataItem500 sxxicc:pub7DataItemHasStringValue ?iracNotesString .
?this sxxicc:pub7ProposalHasDataItem ?dataItem501 .
?dataItem501 a sxxicc:Pub7DataItem501 .
?dataItem501 sxxicc:pub7DataItemHasStringValue ?notesFreeTextCommentsString .
?this sxxicc:pub7ProposalHasDataItem ?dataItem113 .
?dataItem113 a sxxicc:Pub7DataItem113 .
?dataItem113 sxxicc:pub7DataItemHasStringValue ?stationClassString .
?this sxxicc:pub7ProposalHasDataItem ?dataItem300 .
?dataItem300 a sxxicc:Pub7DataItem300 .
?dataItem300 sxxicc:pub7DataItemHasStringValue ?stateCountryForTransmittingStation .
BIND (SUBSTR(?serialNumString, 1, 4) AS ?orgString) .
BIND (SUBSTR(?stationClassString, 1, 2) AS ?stationClassCode) .
FILTER (((((?orgString = "S "^^xsd:string) && (?iracNotesString = "S181"^^xsd:string)) && (?notesFreeTextCommentsString != "M002"^^xsd:string)) && (?stationClassCode = "FX"^^xsd:string)) && (?stateCountryForTransmittingStation = "DC"^^xsd:string)) .
}
为什么此构造函数在现代 PC 上运行如此缓慢(AMD 四核 2.3 GHz,运行 Windows 8,具有 16 GB 物理内存并且没有显着的额外应用程序加载)?其他构造函数在同一台机器上快速运行,并使用相同的事实做明显相似的事情。
这是执行此示例的 Jave VisualVM 采样器输出:
RDF4J org.eclipse.rdf4j.common.concurrent.locks.LockManager$1.release() 和 org.eclipse.rdf4j.common.concurrent.locks.LockManager.createLock() 支配着 Self Time。为什么??我可以做些什么来重写我的规则以避免这种时间消耗?
笔记:
- WHERE 子句的第一个三元组在 SPIN 构造函数中不是必需的,因为 ?this 是自动设置的。但是,我包含它是为了通过将此构造函数复制到工作台中的 SPARQL 查询 (Explore/Query) 中来简化调试。我还发现将 CONSTRUCT 子句替换为“SELECT DISTINCT *”很方便,同时保留 WHERE 子句以进行构造函数调试。
- 此构造函数中 WHERE 子句的唯一目的是提供图形模式匹配,以显示 CONSTRUCT 子句中存在的固定错误消息的错误条件。没有绑定从 WHERE 子句转移到 CONSTRUCT 子句中,但 WHERE 子句仍然控制 CONSTRUCT 子句中三元组的断言。
更新
我通过从构造函数中删除一个 FILTER 和关联的三元组来修改构造函数:
FILTER (?iracNotesString = "S181"^^xsd:string) .
?this sxxicc:pub7ProposalHasDataItem ?dataItem500 .
?dataItem500 a sxxicc:Pub7DataItem500 .
?dataItem500 sxxicc:pub7DataItemHasStringValue ?iracNotesString .
这导致在 TBC FE 中显示如下构造函数:
使用相同的 2 个 SPARQL 更新查询运行相同的测试,第二个查询的执行时间非常非线性地减少,从超过 20 秒减少到不到 2 秒。同样,这似乎不正确。