Files
esengine/assets/svg/soa-vs-aos.svg
2025-08-06 17:04:02 +08:00

273 lines
14 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<svg width="800" height="500" xmlns="http://www.w3.org/2000/svg">
<defs>
<!-- 渐变定义 -->
<linearGradient id="soaGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#667eea"/>
<stop offset="100%" style="stop-color:#764ba2"/>
</linearGradient>
<linearGradient id="aosGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#f093fb"/>
<stop offset="100%" style="stop-color:#f5576c"/>
</linearGradient>
<linearGradient id="performanceGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#4facfe"/>
<stop offset="100%" style="stop-color:#00f2fe"/>
</linearGradient>
<!-- 动画定义 -->
<style>
.data-flow {
animation: dataMove 3s ease-in-out infinite;
}
.memory-access {
animation: memoryAccess 2s ease-in-out infinite;
}
.performance-bar {
animation: performanceGrow 2.5s ease-out forwards;
}
.text-reveal {
animation: textReveal 1s ease-in forwards;
opacity: 0;
}
.structure-highlight {
animation: structureHighlight 4s ease-in-out infinite;
}
@keyframes dataMove {
0%, 100% { opacity: 0.6; filter: brightness(1); }
50% { opacity: 1; filter: brightness(1.2); }
}
@keyframes memoryAccess {
0%, 100% { fill: #e2e8f0; }
50% { fill: #3182ce; }
}
@keyframes performanceGrow {
0% { width: 0; opacity: 0.5; }
100% { opacity: 1; }
}
@keyframes textReveal {
0% { opacity: 0; }
100% { opacity: 1; }
}
@keyframes structureHighlight {
0%, 100% { stroke: #cbd5e0; stroke-width: 1; opacity: 0.8; }
50% { stroke: #3182ce; stroke-width: 2; opacity: 1; }
}
</style>
</defs>
<!-- 背景 -->
<rect width="800" height="500" fill="white" rx="15" stroke="#e2e8f0" stroke-width="1"/>
<!-- 标题 -->
<text x="400" y="30" text-anchor="middle" font-family="Arial, sans-serif" font-size="22" font-weight="bold" fill="#2c3e50">
SoA vs AoS 数据结构对比
</text>
<text x="400" y="50" text-anchor="middle" font-family="Arial, sans-serif" font-size="14" fill="#666">
Structure of Arrays vs Array of Structures
</text>
<!-- AoS 部分 (左侧) -->
<g id="aos-section">
<rect x="50" y="80" width="320" height="180" rx="10" fill="url(#aosGradient)" opacity="0.9"/>
<!-- AoS 标题 -->
<text x="210" y="105" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="white">
AoS - Array of Structures
</text>
<text x="210" y="125" text-anchor="middle" font-family="Arial, sans-serif" font-size="12" fill="white">
结构体数组(传统方式)
</text>
<!-- AoS 数据结构示例 -->
<rect x="70" y="140" width="280" height="100" rx="5" fill="rgba(255,255,255,0.2)" stroke="rgba(255,255,255,0.4)" stroke-width="1"/>
<!-- Entity 0 -->
<rect x="85" y="155" width="70" height="15" rx="2" fill="rgba(255,255,255,0.3)" class="structure-highlight"/>
<text x="120" y="166" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="white">Entity[0]</text>
<rect x="85" y="175" width="15" height="8" rx="1" fill="#ff6b6b" class="data-flow"/>
<text x="92" y="181" text-anchor="middle" font-family="Arial, sans-serif" font-size="6" fill="white">x</text>
<rect x="105" y="175" width="15" height="8" rx="1" fill="#4ecdc4" class="data-flow" style="animation-delay: 0.5s"/>
<text x="112" y="181" text-anchor="middle" font-family="Arial, sans-serif" font-size="6" fill="white">y</text>
<rect x="125" y="175" width="15" height="8" rx="1" fill="#45b7d1" class="data-flow" style="animation-delay: 1s"/>
<text x="132" y="181" text-anchor="middle" font-family="Arial, sans-serif" font-size="6" fill="white">hp</text>
<rect x="145" y="175" width="10" height="8" rx="1" fill="#96ceb4" class="data-flow" style="animation-delay: 1.5s"/>
<text x="150" y="181" text-anchor="middle" font-family="Arial, sans-serif" font-size="6" fill="white">id</text>
<!-- Entity 1 -->
<rect x="170" y="155" width="70" height="15" rx="2" fill="rgba(255,255,255,0.3)" class="structure-highlight" style="animation-delay: 1s"/>
<text x="205" y="166" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="white">Entity[1]</text>
<rect x="170" y="175" width="15" height="8" rx="1" fill="#ff6b6b" class="data-flow" style="animation-delay: 2s"/>
<rect x="190" y="175" width="15" height="8" rx="1" fill="#4ecdc4" class="data-flow" style="animation-delay: 2.5s"/>
<rect x="210" y="175" width="15" height="8" rx="1" fill="#45b7d1" class="data-flow" style="animation-delay: 3s"/>
<rect x="230" y="175" width="10" height="8" rx="1" fill="#96ceb4" class="data-flow" style="animation-delay: 3.5s"/>
<!-- Entity 2 -->
<rect x="255" y="155" width="70" height="15" rx="2" fill="rgba(255,255,255,0.3)" class="structure-highlight" style="animation-delay: 2s"/>
<text x="290" y="166" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="white">Entity[2]</text>
<rect x="255" y="175" width="15" height="8" rx="1" fill="#ff6b6b" class="data-flow" style="animation-delay: 4s"/>
<rect x="275" y="175" width="15" height="8" rx="1" fill="#4ecdc4" class="data-flow" style="animation-delay: 4.5s"/>
<rect x="295" y="175" width="15" height="8" rx="1" fill="#45b7d1" class="data-flow" style="animation-delay: 5s"/>
<rect x="315" y="175" width="10" height="8" rx="1" fill="#96ceb4" class="data-flow" style="animation-delay: 5.5s"/>
<!-- 内存访问模式 -->
<text x="210" y="205" text-anchor="middle" font-family="Arial, sans-serif" font-size="10" fill="white">
内存访问:跳跃式访问,缓存不友好
</text>
<path d="M 92 195 Q 112 210 132 195 Q 152 210 177 195" stroke="white" stroke-width="1" fill="none" stroke-dasharray="3,2"/>
<text x="135" y="225" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="white">
处理位置时需跳过其他数据
</text>
</g>
<!-- SoA 部分 (右侧) -->
<g id="soa-section">
<rect x="430" y="80" width="320" height="180" rx="10" fill="url(#soaGradient)" opacity="0.9"/>
<!-- SoA 标题 -->
<text x="590" y="105" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="white">
SoA - Structure of Arrays
</text>
<text x="590" y="125" text-anchor="middle" font-family="Arial, sans-serif" font-size="12" fill="white">
数组结构ECS优化方式
</text>
<!-- SoA 数据结构示例 -->
<rect x="450" y="140" width="280" height="100" rx="5" fill="rgba(255,255,255,0.2)" stroke="rgba(255,255,255,0.4)" stroke-width="1"/>
<!-- Position Array -->
<text x="460" y="155" font-family="Arial, sans-serif" font-size="8" fill="white">Position[]:</text>
<rect x="515" y="145" width="20" height="10" rx="1" fill="#ff6b6b" class="data-flow"/>
<rect x="540" y="145" width="20" height="10" rx="1" fill="#ff6b6b" class="data-flow" style="animation-delay: 0.3s"/>
<rect x="565" y="145" width="20" height="10" rx="1" fill="#ff6b6b" class="data-flow" style="animation-delay: 0.6s"/>
<rect x="590" y="145" width="20" height="10" rx="1" fill="#ff6b6b" class="data-flow" style="animation-delay: 0.9s"/>
<text x="625" y="153" font-family="Arial, sans-serif" font-size="8" fill="white">连续存储</text>
<!-- Velocity Array -->
<text x="460" y="170" font-family="Arial, sans-serif" font-size="8" fill="white">Velocity[]:</text>
<rect x="515" y="160" width="20" height="10" rx="1" fill="#4ecdc4" class="data-flow" style="animation-delay: 1s"/>
<rect x="540" y="160" width="20" height="10" rx="1" fill="#4ecdc4" class="data-flow" style="animation-delay: 1.3s"/>
<rect x="565" y="160" width="20" height="10" rx="1" fill="#4ecdc4" class="data-flow" style="animation-delay: 1.6s"/>
<rect x="590" y="160" width="20" height="10" rx="1" fill="#4ecdc4" class="data-flow" style="animation-delay: 1.9s"/>
<!-- Health Array -->
<text x="460" y="185" font-family="Arial, sans-serif" font-size="8" fill="white">Health[]:</text>
<rect x="515" y="175" width="20" height="10" rx="1" fill="#45b7d1" class="data-flow" style="animation-delay: 2s"/>
<rect x="540" y="175" width="20" height="10" rx="1" fill="#45b7d1" class="data-flow" style="animation-delay: 2.3s"/>
<rect x="565" y="175" width="20" height="10" rx="1" fill="#45b7d1" class="data-flow" style="animation-delay: 2.6s"/>
<rect x="590" y="175" width="20" height="10" rx="1" fill="#45b7d1" class="data-flow" style="animation-delay: 2.9s"/>
<!-- ID Array -->
<text x="460" y="200" font-family="Arial, sans-serif" font-size="8" fill="white">EntityID[]:</text>
<rect x="515" y="190" width="15" height="10" rx="1" fill="#96ceb4" class="data-flow" style="animation-delay: 3s"/>
<rect x="535" y="190" width="15" height="10" rx="1" fill="#96ceb4" class="data-flow" style="animation-delay: 3.3s"/>
<rect x="555" y="190" width="15" height="10" rx="1" fill="#96ceb4" class="data-flow" style="animation-delay: 3.6s"/>
<rect x="575" y="190" width="15" height="10" rx="1" fill="#96ceb4" class="data-flow" style="animation-delay: 3.9s"/>
<!-- 内存访问模式 -->
<text x="590" y="220" text-anchor="middle" font-family="Arial, sans-serif" font-size="10" fill="white">
内存访问:连续访问,缓存友好
</text>
<path d="M 525 205 L 570 205" stroke="white" stroke-width="2" fill="none" class="data-flow"/>
<text x="590" y="235" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="white">
处理位置时连续访问相同类型数据
</text>
</g>
<!-- 性能对比区域 -->
<g id="performance-comparison">
<rect x="50" y="280" width="700" height="150" rx="10" fill="rgba(248, 249, 250, 0.9)" stroke="#e2e8f0" stroke-width="1"/>
<text x="400" y="305" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="#2c3e50">
性能对比分析
</text>
<!-- 缓存性能对比 -->
<g id="cache-performance">
<text x="80" y="330" font-family="Arial, sans-serif" font-size="12" font-weight="bold" fill="#4a5568">
缓存命中率:
</text>
<!-- AoS 缓存性能 -->
<text x="80" y="350" font-family="Arial, sans-serif" font-size="11" fill="#666">AoS:</text>
<rect x="120" y="342" width="100" height="12" rx="6" fill="#f7fafc" stroke="#e2e8f0" stroke-width="1"/>
<rect x="120" y="342" width="35" height="12" rx="6" fill="url(#aosGradient)" class="performance-bar"/>
<text x="230" y="351" font-family="Arial, sans-serif" font-size="10" fill="#666">35%</text>
<!-- SoA 缓存性能 -->
<text x="80" y="370" font-family="Arial, sans-serif" font-size="11" fill="#666">SoA:</text>
<rect x="120" y="362" width="100" height="12" rx="6" fill="#f7fafc" stroke="#e2e8f0" stroke-width="1"/>
<rect x="120" y="362" width="85" height="12" rx="6" fill="url(#soaGradient)" class="performance-bar" style="animation-delay: 0.5s"/>
<text x="230" y="371" font-family="Arial, sans-serif" font-size="10" fill="#666">85%</text>
</g>
<!-- 处理速度对比 -->
<g id="processing-speed">
<text x="320" y="330" font-family="Arial, sans-serif" font-size="12" font-weight="bold" fill="#4a5568">
批量处理速度:
</text>
<!-- AoS 处理速度 -->
<text x="320" y="350" font-family="Arial, sans-serif" font-size="11" fill="#666">AoS:</text>
<rect x="360" y="342" width="120" height="12" rx="6" fill="#f7fafc" stroke="#e2e8f0" stroke-width="1"/>
<rect x="360" y="342" width="48" height="12" rx="6" fill="url(#aosGradient)" class="performance-bar" style="animation-delay: 1s"/>
<text x="490" y="351" font-family="Arial, sans-serif" font-size="10" fill="#666">2.3x slower</text>
<!-- SoA 处理速度 -->
<text x="320" y="370" font-family="Arial, sans-serif" font-size="11" fill="#666">SoA:</text>
<rect x="360" y="362" width="120" height="12" rx="6" fill="#f7fafc" stroke="#e2e8f0" stroke-width="1"/>
<rect x="360" y="362" width="120" height="12" rx="6" fill="url(#soaGradient)" class="performance-bar" style="animation-delay: 1.5s"/>
<text x="490" y="371" font-family="Arial, sans-serif" font-size="10" fill="#666">baseline</text>
</g>
<!-- 使用场景 -->
<g id="use-cases">
<text x="560" y="330" font-family="Arial, sans-serif" font-size="12" font-weight="bold" fill="#4a5568">
适用场景:
</text>
<text x="560" y="350" font-family="Arial, sans-serif" font-size="10" fill="#666">
✅ SoA: 大量实体的同类型操作
</text>
<text x="560" y="365" font-family="Arial, sans-serif" font-size="10" fill="#666">
✅ SoA: 游戏循环中的系统处理
</text>
<text x="560" y="380" font-family="Arial, sans-serif" font-size="10" fill="#666">
❌ AoS: 混合操作、少量实体
</text>
<text x="560" y="395" font-family="Arial, sans-serif" font-size="10" fill="#666">
❌ AoS: 随机访问模式
</text>
</g>
</g>
<!-- ECS 框架优势说明 -->
<g id="ecs-advantage">
<rect x="50" y="450" width="700" height="40" rx="8" fill="rgba(67, 233, 123, 0.1)" stroke="#43e97b" stroke-width="1"/>
<text x="400" y="468" text-anchor="middle" font-family="Arial, sans-serif" font-size="14" font-weight="bold" fill="#2d3748">
🚀 本框架采用 SoA 优化存储,@EnableSoA 装饰器自动转换,性能提升 2-3 倍
</text>
<text x="400" y="485" text-anchor="middle" font-family="Arial, sans-serif" font-size="12" fill="#4a5568">
支持热切换存储方式,开发时使用 AoS 调试,生产环境自动启用 SoA 优化
</text>
</g>
</svg>