2024년 12월 30일 월요일
2024년 6월 17일 월요일
2024년 6월 16일 일요일
2024년 3월 13일 수요일
7 NEW JavaScript 2024 Features
Well-Formed Unicode Strings
Usage in Action
Imagine you’re working with user-generated content that may include a variety of languages and symbols.
Ensuring this content is correctly encoded is crucial for processing and displaying it without errors.
- Check for well-formed Unicode strings: Determine if a string is correctly encoded without any lone surrogates using
String.prototype.toWellFormed
.
const exampleString = "Example with Unicode 🌈";
console.log(exampleString.isWellFormed()); // True if no lone surrogates are present
Atomic waitSync
Atomic waitSync is a synchronization primitive that complements the existing Atomics API.
It allows for synchronous waiting on a shared memory location, facilitating better coordination between main threads and workers, which is crucial in complex, multi-threaded web applications.
Synchronization Example
In a web application that performs heavy computations or real-time data processing in web workers.
This coordinates the main thread with worker threads efficiently is key to maintaining performance and data integrity.
// Assuming a shared Int32Array buffer
const sharedBuffer = new SharedArrayBuffer(1024);
const intArray = new Int32Array(sharedBuffer);
// Main thread sets a value
Atomics.store(intArray, 0, 123);
// Worker thread waits synchronously for the value to change
Atomics.waitSync(intArray, 0, 123);
// After some operations in the worker
Atomics.store(intArray, 0, 456); // Changes the shared memory value
// Main thread can be notified or act upon this change
Atomic waitSync enhances JavaScript’s concurrency model by providing a more straightforward way to synchronize operations between the main thread and web workers without resorting to complex and error-prone messaging or polling mechanisms.
It could significantly improve the performance and reliability of applications that rely on parallel processing.
Pipeline Operator (|>)
The Pipeline Operator introduces a more readable and functional way to write sequences of operations in JavaScript.
It allows developers to chain functions together in a manner that is more intuitive and cleaner than nested function calls, improving the legibility and maintainability of code, especially in data processing or functional programming contexts.
Example
Consider a scenario where you need to apply multiple transformations to a value. With the Pipeline Operator, each step is clearly separated, making the code easier to follow.
// Example functions that could be used in a pipeline
const double = n => n * 2;
const increment = n => n + 1;
// Using the Pipeline Operator to apply the functions
let result = 5 |> double |> increment;
console.log(result); // Outputs 11
The Pipeline Operator represents a significant step towards a more functional programming style within JavaScript.
Offering a syntactic solution that is not only more expressive but also aligns with the readability and compositional goals of modern JavaScript development.
Temporal API
The Temporal API addresses the complexities and inconsistencies of date and time manipulation in JavaScript.
By providing a big set of objects and methods for dealing with dates, times, timezones, and durations, the Temporal API simplifies working with time-related data.
In this way it aimis to replace the need for third-party libraries with a robust, standard solution.
Temporal API in Use
Working with dates and times often involves dealing with time zones, daylight saving time changes, and formatting.
The Temporal API makes these tasks more straightforward and less error-prone.
// Creating a date-time object in a specific timezone
const meetingDate = Temporal.PlainDateTime.from("2024-03-25T15:00:00");
const zonedDate = meetingDate.withTimeZone("America/New_York");
console.log(zonedDate.toString()); // "2024-03-25T15:00:00-04:00[America/New_York]"
// Calculating the difference between two dates
const startDate = Temporal.PlainDate.from("2024-01-01");
const endDate = Temporal.PlainDate.from("2024-03-01");
const difference = startDate.until(endDate);
console.log(difference.toString()); // "P2M" (Period of 2 Months)
This feature is a great improvement over the existing Date object, because it offers developers a more intuitive and powerful toolset for all aspects of date and time manipulation.
It greatly enhances the development experience when handling temporal data in JS applications.
Records and Tuples
Records and Tuples are proposed as new, immutable data structures in JavaScript, aiming to improve code reliability and simplicity.
- Records allow you to create immutable key-value pairs, similar to Objects but without the ability to change once created.
- Tuples are immutable ordered lists, akin to Arrays but also unchangeable after creation.
These structures ensure that data doesn’t get altered unexpectedly, which is particularly useful in functional programming and when managing application state.
Example
Let’s explore how Records and Tuples can be applied in a user profile management scenario to maintain data integrity throughout an application’s lifecycle.
Creating Immutable User Profiles with Records:
- Use Records for defining user profiles as unchangeable key-value pairs, ensuring that once a user’s profile is set, it cannot be altered, thus preserving data integrity.
const userProfile = #{
name: "Jane Doe",
age: 28,
};
Managing Ordered Data with Tuples:
- Implement Tuples for handling sequences of data, such as points or coordinates, which remain constant once initialized, eliminating the risk of accidental modification.
const points = #[1, 2, 3];
Additionally they offer a level of assurance about the state of your data throughout your application’s execution, preventing bugs that stem from unintended mutations.
They are especially beneficial in applications with complex state management needs or where functional programming patterns are employed.
2024년 1월 23일 화요일
PostgreSQL : CPU를 많이 사용하는 SQL 쿼리
PostgreSQL 버전 12 이하:
pss.userid,
pss.dbid,
pd.datname as db_name,
round(pss.total_time::numeric, 2) as total_time,
pss.calls,
round(pss.mean_time::numeric, 2) as mean,
round((100 * pss.total_time / sum(pss.total_time::numeric) OVER ())::numeric, 2) as cpu_portion_pctg,
pss.query
FROM pg_stat_statements pss, pg_database pd
WHERE pd.oid=pss.dbid
ORDER BY pss.total_time
DESC LIMIT 30;
PostgreSQL 버전 13 이상:
SELECT
pss.userid,
pss.dbid,
pd.datname as db_name,
round((pss.total_exec_time + pss.total_plan_time)::numeric, 2) as total_time,
pss.calls,
round((pss.mean_exec_time+pss.mean_plan_time)::numeric, 2) as mean,
round((100 * (pss.total_exec_time + pss.total_plan_time) / sum((pss.total_exec_time + pss.total_plan_time)::numeric) OVER ())::numeric, 2) as cpu_portion_pctg,
pss.query
FROM pg_stat_statements pss, pg_database pd
WHERE pd.oid=pss.dbid
ORDER BY (pss.total_exec_time + pss.total_plan_time)
DESC LIMIT 30;
출력 텍스트가 너무 긴 경우 SQL 쿼리 수정할.
PostgreSQL 버전 12 이하:
SELECT
pss.userid,
pss.dbid,
pd.datname as db_name,
round(pss.total_time::numeric, 2) as total_time,
pss.calls,
round(pss.mean_time::numeric, 2) as mean,
round((100 * pss.total_time / sum(pss.total_time::numeric) OVER ())::numeric, 2) as cpu_portion_pctg,
substr(pss.query, 1, 200) short_query
FROM pg_stat_statements pss, pg_database pd
WHERE pd.oid=pss.dbid
ORDER BY pss.total_time
DESC LIMIT 30;
PostgreSQL 버전 13 이상:
SELECT
pss.userid,
pss.dbid,
pd.datname as db_name,
round((pss.total_exec_time + pss.total_plan_time)::numeric, 2) as total_time,
pss.calls,
round((pss.mean_exec_time+pss.mean_plan_time)::numeric, 2) as mean,
round((100 * (pss.total_exec_time + pss.total_plan_time) / sum((pss.total_exec_time + pss.total_plan_time)::numeric) OVER ())::numeric, 2) as cpu_portion_pctg,
substr(pss.query, 1, 200) short_query
FROM pg_stat_statements pss, pg_database pd
WHERE pd.oid=pss.dbid
ORDER BY (pss.total_exec_time + pss.total_plan_time)
DESC LIMIT 30;