今日已更新 233 条资讯 | 累计 20205 条内容
关于我们

标签:#Performance

找到 115 篇相关文章

开发者

NetworkX vs CSR + TensorPrimitives: PageRank on 28M Edges

Overview PageRank is the canonical graph algorithm. NetworkX implements it in pure Python — its dict-of-dict adjacency representation means every power-iteration step dispatches millions of Python attribute lookups. When the graph has 1.8 million nodes and 28.5 million edges (Wikipedia category hyperlinks), those lookups dominate the runtime. The .NET replacement uses a CSR (Compressed Sparse Row) matrix — two flat int[] arrays for the graph structure — and TensorPrimitives for the SIMD-accelerated normalization step inside each iteration. Benchmark Setup Five SNAP datasets of increasing size: Dataset Nodes Edges wiki-Vote 7,115 103,689 soc-Epinions1 75,879 508,837 web-Stanford 281,903 2,312,497 web-Google 875,713 5,105,039 wiki-topcats 1,791,489 28,511,807 Algorithm: power-iteration PageRank, damping=0.85, tol=1e-6. Both implementations converge to identical top-10 node rankings. Results Dataset Python (NetworkX) .NET (CSR) Speedup wiki-Vote (103k edges) ~0.8 s ~100 ms ~8× soc-Epinions1 (508k edges) ~8 s ~600 ms ~13× web-Stanford (2.3M edges) ~120 s ~5 s ~24× web-Google (5.1M edges) ~5.5 min ~12 s ~28× wiki-topcats (28.5M edges) ~47 min ~60 s ~47× The speedup grows with graph size because NetworkX's Python dispatch cost scales with edge count, while the CSR inner loop is a tight JIT-compiled SIMD pass. Why CSR Beats NetworkX NetworkX represents each node's neighbors as a Python dict. Iterating the adjacency in one power-iteration step means: Calling G.neighbors(node) — a Python method call Iterating a dict — unboxing int keys, chasing heap pointers Accumulating a float into another dict value — another boxing step That happens for every edge, every iteration, roughly 50–80 times to convergence. CSR collapses the graph to two arrays: rowPtr[n+1] (where each node's neighbors start) and colIdx[edges] (the neighbor list). Iterating neighbors of node v is a tight C loop from rowPtr[v] to rowPtr[v+1] . No Python objects, no dict hashing, no pointer chasing. Key Code // P

2026-06-01 原文 →
AI 资讯

The Fastest Part of Your Stack Is Already Installed: Rethinking Web IDEs

There is a fascinating psychological phenomenon in modern software engineering: the relentless pursuit of the upgrade. As frontend developers, we are conditioned to believe that speed and efficiency come from adopting the newest technologies. We migrate from Webpack to Vite to shave seconds off our build times. We transition between UI libraries in search of better reconciliation algorithms. We constantly audit our CI/CD pipelines. We treat performance as a destination we must reach by continuously adding or swapping out the moving parts of our toolchain. Yet, amidst this endless cycle of optimization, we consistently overlook the most sophisticated, highly optimized piece of software in our entire stack. It is the software you are using to read this article right now: the web browser. The Underappreciated Engine The modern browser is an absolute marvel of engineering. Over the past decade, teams of the world's most talented systems engineers have engaged in a fierce arms race to optimize browser engines like V8, SpiderMonkey, and JavaScriptCore. Today’s browsers feature Just-In-Time (JIT) compilation, sophisticated garbage collection, and massively parallelized rendering pipelines. They are capable of executing highly complex, interactive applications with a level of fluidity that was unimaginable a few years ago. However, when we evaluate developer tools—specifically the online IDE or the browser-based code editor—there is a stark contrast. The environments we use to write and test our code rarely reflect the speed of the engine they run inside. Why the Standard Web IDE Misses the Mark If you want to quickly prototype a component or isolate a bug, you will likely reach for a frontend playground or a popular Replit alternative. What happens next is often a masterclass in friction. The environment feels heavy. The interface is cluttered with features you didn't ask for. As you type, the live code editor experiences micro-stutters. The instant live preview isn't actu

2026-05-31 原文 →
AI 资讯

Notes on Serving LLMs with TensorRT-LLM and Triton

Notes on Serving LLMs with TensorRT-LLM and Triton 2026-05-31 · LLM serving / NVIDIA stack These are working notes on taking an open-weights LLM from a Hugging Face checkpoint to a production-style serving endpoint on the NVIDIA stack — TensorRT-LLM for the engine, Triton Inference Server for the deployment surface — and benchmarking it honestly against vLLM on multi-GPU hardware. They follow the harness in trtllm-triton-serving (4× H100, NVLink). The goal is to move from "I use vLLM" to "I can stand up the NVIDIA inference stack on real multi-GPU hardware and reason about the trade-offs." 1. The serving pipeline The path from checkpoint to endpoint has four stages. Each one is a place where a decision affects latency, throughput, or accuracy: Checkpoint — a Hugging Face model. Engine build — compile to a TensorRT-LLM engine for a fixed tensor-parallel degree, precision, and batching policy. Model repository — wrap the engine in a Triton tensorrt_llm -backend model repo. Serving + load test — trtllm-serve (or Triton) exposes an OpenAI-compatible endpoint; a load generator drives it under controlled concurrency. The key mental shift from vLLM: TensorRT-LLM does ahead-of-time compilation . vLLM is a runtime that takes the model and serves it; TensorRT-LLM builds an engine specialized to your GPU, TP degree, and precision first. That build is where the performance comes from, and also where the rigidity comes from. 2. Tensor parallelism (TP) For a model that doesn't fit on one GPU — or to cut latency — TensorRT-LLM shards each layer across GPUs. On a 4× H100 NVLink box, TP=4 means every forward pass does an all-reduce across the four GPUs over NVLink. The all-reduce is not free. On this fabric it tops out around 77 % of the NVLink budget (see the separate NVLink-wall notes ). For prefill (large tensors) you're bandwidth-bound and TP helps. For decode (one token at a time) you're pinned against the small-message latency floor, and past a point more TP makes decode slowe

2026-05-31 原文 →
AI 资讯

C_STD : A Leak-Free, Cross-Platform Standard Library for Modern C

c_std: A Leak-Free, Cross-Platform Standard Library for Modern C Bringing the comfort of the C++ STL and Python's standard library to C17 — without leaving C A technical white paper. Executive summary C is still the substrate of the computing world — kernels, databases, language runtimes, embedded firmware, and the inner loops of nearly everything else. Yet the moment you step away from the kernel and try to write ordinary application code in C, you feel the gap: no growable vector, no hash map, no JSON parser, no string type that doesn't invite a buffer overflow. You either pull in a grab-bag of mismatched third-party libraries, each with its own conventions and failure modes, or you re-implement the same dynamic array for the hundredth time. c_std is an attempt to close that gap deliberately and coherently. It is a single, consistent library — written in pure C17 — that reimplements a large slice of the C++ Standard Library (containers, algorithms, smart pointers) alongside many Python-style conveniences ( json , regex , random , statistics , csv , config , even turtle graphics). It targets Windows and Linux from one source tree, compiles cleanly under -Wall -Wextra , and — this is the part I care about most — is verified leak-free under Valgrind , module by module, example by example. This paper explains the design philosophy, the architecture, and the engineering discipline that makes a library like this trustworthy enough to build on. 1. The problem: C's missing middle Every C programmer knows the two extremes. At the bottom, the language itself: pointers, malloc , memcpy , raw arrays. At the top, whatever the platform hands you — <windows.h> or POSIX, OpenSSL, a JSON library someone wrapped a decade ago. The middle — the layer the C++ STL and Python's batteries-included standard library occupy — is missing. That missing middle has a real cost. It shows up as: Re-invention. Teams write their own vector, their own string builder, their own linked list, each subt

2026-05-31 原文 →
AI 资讯

22 Astro Best Practices: The Bookmark-Worthy Tips

22 Astro Best Practices: The Bookmark-Worthy Tips At QuotyAI I'm using Astro to build landing pages and blog posts, so I have hands-on experience how to use it properly and how to vibe-code without headache. Astro is the best framework for content sites right now - #1 in developer satisfaction in the State of JS 2025 survey, with Cloudflare backing it since January 2026. But like any tool, it rewards people who use it the way it was designed. This is the reference I wish I had when I started. Whether you're building your first Astro project or vibe-coding a blog at 2am, these are the habits worth forming from day one. Heads up on versions: This article covers Astro 6.x (released March 2026) and Astro 6.4 (released May 2026). Some APIs from older tutorials are now deprecated - those are called out explicitly below. Always check the upgrade guide when moving between majors. 🖼️ Assets & Media 1. Use <Image /> instead of <img /> Astro's built-in <Image /> component does a lot of work at build time that plain <img> tags leave on the table: it converts images to WebP, generates the right width and height attributes to prevent layout shift, and compresses everything without you touching a single config file. --- import { Image } from 'astro:assets'; import hero from '../assets/hero.png'; --- <!-- ✅ Optimized: converted to WebP, compressed, no layout shift --> <Image src={hero} alt="Hero image" /> <!-- ❌ Skips all of that --> <img src="/hero.png" alt="Hero image" /> For art-direction scenarios (different images at different breakpoints), reach for <Picture /> instead. 2. Use the Astro 6 Built-in Fonts API Almost every website uses custom fonts, but getting them right is surprisingly complicated - performance tradeoffs, privacy concerns, self-hosting, fallback generation, and preload hints. Astro 6 added a built-in Fonts API that handles all of it for you. Configure your fonts in astro.config.mjs : // astro.config.mjs import { defineConfig , fontProviders } from ' astro/conf

2026-05-30 原文 →
AI 资讯

UUID v4 vs UUID v7 — Lequel choisir pour PostgreSQL en 2026 ?

Si vous utilisez PostgreSQL, vous avez probablement déjà dû choisir entre une clé primaire BIGSERIAL et un UUID. Depuis des années, la version 4 (aléatoire) est le choix par défaut quand on veut un identifiant unique et distribué. Mais en 2026, une alternative plus récente s’impose : UUID v7, qui intègre un timestamp et promet de meilleures performances pour les index. Dans cet article, je vous explique concrètement ce qui change, avec des benchmarks PostgreSQL et des exemples de code, pour que vous puissiez décider en connaissance de cause. UUID v4 : le standard aléatoire et son problème d’index Un UUID v4 est constitué de 122 bits aléatoires. Cette absence totale de tri est sa force pour l’unicité, mais elle devient un handicap dans un index B‑tree, qui est la structure utilisée par PostgreSQL pour les clés primaires. Lorsque vous insérez un nouvel UUID v4, il a autant de chances de se retrouver au début de l’index qu’à la fin. Résultat : l’index se fragmente, les pages se remplissent mal, et les performances d’écriture se dégradent à mesure que la table grossit. J’ai reproduit un test simple sur PostgreSQL 16 avec 10 millions de lignes, en utilisant une table dont la seule différence est la colonne id : -- Table UUID v4 CREATE TABLE events_v4 ( id UUID DEFAULT gen_random_uuid () PRIMARY KEY , payload JSONB , created_at TIMESTAMPTZ DEFAULT now () ); -- Table UUID v7 (généré côté application, voir plus bas) CREATE TABLE events_v7 ( id UUID PRIMARY KEY , payload JSONB , created_at TIMESTAMPTZ DEFAULT now () ); Après insertion, voici les mesures : Type de clé Taille de l’index Fragmentation Latence moyenne d’insertion BIGINT ~214 Mo 0 % ~0,8 ms/ligne UUID v4 ~428 Mo (2×) 99 % ~4,8 ms/ligne UUID v7 ~428 Mo (2×) ~2 % ~1,1 ms/ligne Ce qui frappe, c’est la fragmentation quasi nulle de l’UUID v7. L’index reste compact et les insertions sont presque aussi rapides qu’avec un BIGSERIAL. L’UUID v4, lui, est plus de quatre fois plus lent à l’insertion sur ce volume. UUID v7 :

2026-05-30 原文 →
AI 资讯

I Ran 200+ Website Audits — Here's What's Actually Broken in 2026

Over the last few weeks I built a website audit tool and ran it on 200+ small business and service websites — dental practices, plumbing companies, landscapers, law firms, real estate agents. Not Fortune 500 pages optimized by dedicated teams. The sites that actually serve local customers. I expected some issues. I did not expect this. Here's the raw data, the patterns I found, and what you can actually do about it. The Scorecard I grade sites across five dimensions on a 0–100 scale. Here are the averages from 200+ audits: Dimension Average Score Worst Score Speed 56 11 SEO 68 29 Mobile usability 61 18 Accessibility 52 8 Security 70 17 SEO and security tend to be passable (automated checks from Google Search Console and automatic SSL help). Speed and accessibility are consistently neglected — probably because the feedback loop is invisible. A slow or inaccessible site loses visitors silently, and the owner never knows why. Finding #1: 67% of Sites Ship >50% Unused CSS This was the single most surprising data point by far. When a browser loads a page, it downloads every byte of CSS, parses it, builds style rules for every selector, and only then paints. If 60% of those rules never get applied (because they target a contact form behind a click, or a mobile menu at 768px+), the browser still processed them. Worst case: a dental practice shipped 287 KB of CSS. Only 31 KB was used on first paint. That's 256 KB of unnecessary render-blocking weight that delayed First Contentful Paint by roughly 1.4 seconds. The fix: If you're using Tailwind, make sure tree-shaking is enabled. If you're writing vanilla CSS, open DevTools > Coverage tab > Reload. Anything over 40% unused is worth addressing. Most bundlers handle this — you just need to turn it on. Finding #2: Average Image Payload Is 1.8 MB — Way Too High Average image payload across all scanned sites: 1.8 MB per page. Only 34% serve WebP or AVIF (modern formats that cut file size by 30-50%). Only 28% serve responsive sizes

2026-05-30 原文 →
AI 资讯

Rust Was Not the Silver Bullet I Expected for Our Treasure Hunt Engine

The Problem We Were Actually Solving I still remember the day our treasure hunt engine started to show its weaknesses. We had been using a custom-built solution written in Java, and it had served us well until our user base grew exponentially. The engine, which relied heavily on recursive searches and dynamic memory allocation, began to cause performance issues and occasional crashes. Our team was under pressure to find a solution that would allow our server to scale without sacrificing the user experience. After some research, I became convinced that Rust was the answer to our problems. Its focus on memory safety and performance seemed like the perfect fit for our needs. What We Tried First (And Why It Failed) Our first attempt at solving the problem was to simply translate our Java code into Rust. We thought that the language's built-in features would automatically solve our performance and memory issues. However, we quickly realized that this approach was not going to work. The Rust compiler was complaining about lifetime issues and borrow checker errors, which we did not fully understand at the time. We spent weeks trying to fix these issues, but our code was still not stable. I recall one particularly frustrating error message from the Rust compiler: error: cannot borrow self.list as mutable because it is also borrowed as immutable. It was then that I realized we needed to take a step back and rethink our approach. The Architecture Decision We decided to start from scratch and redesign our treasure hunt engine with Rust's strengths in mind. We chose to use a graph-based data structure, which allowed us to take advantage of Rust's ownership model and avoid common pitfalls like null pointer dereferences. We also made use of the crossbeam crate for parallelism and the tokio crate for async I/O. This new design required us to think differently about our problem domain, but it ultimately led to a more efficient and scalable solution. I was impressed by the level of

2026-05-30 原文 →
AI 资讯

Secure Your Microservices: Meet Halimun, the High-Performance Encrypted Proxy

Meet Halimun Proxy a high-performance, ultra-low latency proxy tunnel system built from the ground up in Rust. Why Rust? By leveraging Rust , Halimun achieves extreme efficiency. Using the Axum web framework and Tokio for non-blocking asynchronous I/O, it manages to maintain a tiny footprint—running on as little as ~15MB of RAM . It’s designed to be fast, memory-safe, and incredibly stable under load. Core Security Features Halimun isn't just a proxy; it’s a security layer. It enforces strict request validation to ensure your internal services are never exposed to malicious actors: AES-256-CBC Encryption: End-to-end payload masking. Even if your traffic is intercepted, the actual API endpoint and data remain indecipherable. HMAC-SHA256 Integrity: Validates that data hasn't been tampered with in transit. Replay Attack Prevention: Uses Nonce and timestamp verification in-memory (via DashMap ) to reject duplicate spoofed requests. SSRF Protection: Built-in mechanisms to prevent attackers from targeting your internal network infrastructure (e.g., 127.0.0.1 ). Camouflage Routing: It hides your actual API structure behind random, dummy URL segments, making traffic profiling by WAFs or human analysts nearly impossible. Quick Start (Docker) Halimun is "Docker-ready," making it easy to drop into any existing infrastructure. 1. Configuration First, generate your encryption keys using the built-in generator: # Generate keys and save to .env docker build -t halimun-proxy . docker run --rm halimun-proxy ./halimun-proxy --keygen --format = env > .env 2. Deployment Configure your config.yaml to map your backend services, then launch your cluster: docker-compose up -d Your production proxy is now live, listening securely on port 80 while your backend services remain completely secluded within a private Docker network. Under the Hood: Request Lifecycle Halimun uses an encrypted tunnel approach. A typical request follows this structure: POST /proxy/1/SEGMENT1/SEGMENT2/SEGMENT3/SEGMEN

2026-05-29 原文 →
AI 资讯

Gas Optimization Part 4: Solidity Tips for Cheaper Contracts

Every line of your smart contract costs something. Some lines cost more than others. In this part of our gas saving series, we’ll explore how to write smarter Solidity code that keeps your contract lean and efficient. Here are six simple and practical ways to reduce gas costs while writing Solidity smart contracts. 1. Use payable Only When Needed, But Know It Saves Gas In Solidity, a function marked payable can actually use slightly less gas than a non-payable one. Even if you're not sending ETH, the EVM skips some internal checks when the function is marked payable. See this example: function hello() external payable {} // 21,137 gas function hello2() external {} // 21,161 gas That tiny difference may not seem like much, but across thousands of calls, it adds up. Only use payable when your function is actually meant to accept ETH 2. Use unchecked for Safe Arithmetic When You’re Sure Since Solidity 0.8.0, all arithmetic operations automatically check for overflows and underflows. While this makes contracts safer, it also uses extra gas. When you're certain that overflow won't occur, you can use the unchecked keyword to skip these safety checks. uint256 public myNumber = 0; function increment() external { unchecked { myNumber++; } } Gas used: 24,347 (much cheaper than using safe math) Warning: Use unchecked carefully. Only when you're confident there's no risk of overflow. 3. Turn On the Solidity Optimizer The Solidity Optimizer is like a smart helper that cleans up and tightens your compiled bytecode. It does not change how your contract works, but it removes waste and makes it cheaper to run. If you’re using tools like Hardhat or Remix, always enable the Optimizer before deploying to mainnet. 4. Use uint256 Instead of Smaller Integers (Most of the Time) Smaller types like uint8 or uint16 might look more efficient, but they can cost more gas during execution. That’s because the EVM automatically converts them to uint256 behind the scenes. So, if you're not tightly p

2026-05-29 原文 →
AI 资讯

Frontend Engineering in 2026: Mastering Performance and DX

The Redefinition of "Frontend Engineer" in 2026 The era of the frontend engineer as a purely visual specialist is over. In 2026, companies like Vercel, Linear, Figma, Shopify, and major FAANG divisions expect their frontend engineers to think in terms of systems, not just components. A modern frontend engineer must understand rendering pipelines, browser internals, network optimization, and component architecture at the same depth that a backend engineer understands database indexing or API design. This shift is reflected directly in how companies interview frontend candidates. If you walk into a 2026 frontend interview expecting to answer "what's the difference between let and const ," you will be humbled. This guide covers everything you need to know to pass a senior-level frontend interview at a top tech company. Core Web Vitals: The Mandatory Topic You Can't Skip Google's Core Web Vitals have become a standard lens through which senior frontend engineers are evaluated. Interviewers now routinely ask candidates to diagnose performance bottlenecks using CWV metrics. The three primary metrics are: LCP (Largest Contentful Paint): Measures perceived load speed. Target under 2.5 seconds. Optimized via image preloading, server-side rendering, and CDN caching. INP (Interaction to Next Paint): Replaced FID in 2024. Measures responsiveness. Optimized by breaking up long tasks, using web workers, and deferring non-critical JavaScript. CLS (Cumulative Layout Shift): Measures visual stability. Prevents jarring layout shifts by pre-defining dimensions for images, iframes, and dynamic content. Be prepared to walk through a real-world scenario: "Given an LCP score of 4.2s, what is your systematic debugging and optimization approach?" This is now a standard senior frontend interview question. React 19 and the Concurrent Rendering Model React 19 introduced a fully concurrent rendering model that fundamentally changes how components behave. Key concepts interviewers probe in 2026

2026-05-29 原文 →
AI 资讯

This Rewrite Isnt the Constraint: How a 300ms Tail Latency Hunt Led to a New Event Pipeline

We were burning 400ms in p99 tail latency on a core event-processing path in Veltrix. The upstream teams kept blaming the network, but the numbers didnt lie—64% of the time was spent inside the JVM, specifically in sun.misc.Unsafe.park during GC pauses. Every time we hit 80% heap pressure, the throughput collapsed and we lost 300k events per minute. That was the exact moment I stopped believing in the JVM as the runtime and started looking at the system boundary. The first attempt was aggressively tuned HotSpot with G1GC and pinning the critical threads to their own NUMA nodes. We set -XX:MaxGCPauseMillis=20 , -XX:+UseNUMA , and even migrated to Azul Zulu Prime because its handling of large heaps was supposedly better. The p99 dropped to 280ms, but the GC telemetry still showed a sawtooth pattern of 30–40ms spikes every 230ms on a 16GB heap. Profiling with JDK Flight Recorder told us 18% of CPU time was spent in card-table scanning. At that point I knew we were fighting the runtime, not the problem. The event pipeline was small—just JSON parsing, enrichment, and a single RocksDB write—but the JVMs generational collector couldnt stop moving objects. The architecture decision came during a four-day blackout window after a failed Blue-Green deploy. Three of us sat in a war room with a single Grafana dashboard showing 100% CPU steal time on the Kubernetes nodes. We had two choices: squeeze more life out of the JVM by manually balancing the heap or rewrite the critical hot path in Rust and give the compiler full control over memory layout. The Rust option meant losing the JVM ecosystem (no more async-profiler, no more one-liner heap dumps) but gave us stackless futures, zero-cost abstractions, and compile-time memory safety. We chose Rust. We forked the Cargo.toml wed used in a sidecar for metrics and started porting the event collector. The numbers after the rewrite told the story. We recompiled the same two endpoints— POST /events and GET /aggregates —and served them f

2026-05-29 原文 →
AI 资讯

Demystifying WebP to PNG: Secure Serverless Edge Routing Configurations Without Leaking Credentials

Demystifying WebP to PNG: How to Secure Serverless Edge Routing Configurations Safely We have all been there. You are building a high-performance, modern web application and you decide to store all user-generated assets in modern, ultra-compressed WebP formats. It is a smart move for your Google Lighthouse scores. Then, the legacy enterprise integration request hits your inbox. A major client needs to pull these same assets dynamically, but their internal 15-year-old reporting engine only supports PNG. Suddenly, you need to configure a runtime conversion pipeline that handles complex input schemas, transforms formats on the fly, and manages edge routes without exposing your internal database claims or API secrets. Setting up secure serverless edge routing configurations to convert images on-demand can quickly turn into a security nightmare. If you do not handle incoming credential tokens correctly, you risk forwarding sensitive OAuth scopes or database keys directly to downstream image-processing worker nodes. In this guide, we will break down exactly how to architect a lightweight, secure, and fast edge routing pipeline that validates incoming image request schemas and converts WebP to PNG without leaking sensitive backend credentials. The Problem Modern edge runtimes like Cloudflare Workers, Vercel Edge Functions, or AWS CloudFront Functions are incredibly fast, but they have strict execution limits. They run on V8 isolates, meaning you do not have a full Node.js environment with unlimited memory and access to heavy C++ binaries like sharp or canvas without paying a massive cold-start penalty. If you want to support legacy clients by converting WebP to PNG on the fly, you are faced with three major challenges: Bundle Size Restrictions : Edge functions typically restrict your code size to 1MB or 2MB. Bundling heavy native libraries to parse image bytes is a recipe for deployment failures. Credential Leakage : Edge routers often intercept incoming JWT authorization

2026-05-28 原文 →
AI 资讯

Article: Stragglers, Not Failures: How Adaptive Hedged Requests Reduce p99 Latency by 74 Percent

n fan-out microservice architectures, slow-but-completing requests accumulate across services and drive p99 latency far higher than per-service metrics suggest. This article presents an adaptive hedging mechanism that uses DDSketch for real-time quantile estimation, windowed rotation to handle distribution drift, and a token-bucket budget to prevent load amplification. By Prathamesh Bhope

2026-05-28 原文 →
AI 资讯

Why Does Using an ORM Decrease Database Performance? An Experience...

Why Does Using an ORM Decrease Database Performance? While trying to optimize the shipping module in a production ERP, I noticed that database queries were incredibly slow. At first, I examined the SQL queries and checked the indexes. However, I couldn't get the performance boost I expected. The problem lay in the Object-Relational Mapper (ORM) library, which was the cornerstone of our application. ORMs make things easier for software developers by providing an abstract layer for database operations, but this convenience often comes at a performance cost. In this post, I will explain why using an ORM decreases database performance, using concrete examples from my own field experience. The core promise of ORMs is to keep developers away from SQL and allow them to interact with databases in a way that is more aligned with the object-oriented paradigm. This is a huge advantage, especially in small and medium-sized projects or rapid prototyping processes. However, when things get complex and performance becomes critical, the efficiency of the queries generated by ORMs starts to be questioned. In many cases I have encountered, especially in enterprise software development processes, the default behaviors of ORMs created an unexpected load on database servers. Query Inefficiencies Generated by ORMs ORMs usually manage database relationships using mechanisms like "eager loading" or "lazy loading". Depending on the developer's preference, these mechanisms either fetch all related data at once (eager loading) or fetch it in pieces as needed (lazy loading). However, ORMs may not always perform these loads in the most optimized way. For example, while only a few fields like ID and name are sufficient in a list view, the ORM might query the entire table or all related tables. This situation causes unnecessary data transfer and unnecessarily overloads the database server. To give an example, on the order list screen of an e-commerce site, we needed to display the customer inform

2026-05-28 原文 →