Việc hiểu danh sách và các hàm chức năng có nhanh hơn “vòng lặp for” không?

172
Ericson Willians 2014-03-01 14:38.

Xét về hiệu suất bằng Python, là một danh sách-hiểu, hoặc các chức năng thích map(), filter()reduce()nhanh hơn so với một vòng lặp for? Tại sao, về mặt kỹ thuật, chúng chạy với tốc độ C , trong khi vòng lặp for lại chạy với tốc độ máy ảo python ?.

Giả sử rằng trong một trò chơi mà tôi đang phát triển, tôi cần vẽ các bản đồ phức tạp và khổng lồ bằng cách sử dụng các vòng lặp. Câu hỏi này chắc chắn sẽ có liên quan, ví dụ: nếu khả năng hiểu danh sách thực sự nhanh hơn, nó sẽ là một lựa chọn tốt hơn nhiều để tránh bị trễ (Mặc dù độ phức tạp trực quan của mã).

7 answers

160
Noname 2014-03-01 14:56.

Sau đây là hướng dẫn sơ bộ và phỏng đoán được giáo dục dựa trên kinh nghiệm. Bạn nên timeithoặc lập hồ sơ trường hợp sử dụng cụ thể của mình để có được những con số khó và những con số đó đôi khi có thể không đồng ý với những điều bên dưới.

Việc hiểu danh sách thường nhanh hơn một chút so với forvòng lặp chính xác tương đương (thực sự tạo ra một danh sách), rất có thể vì nó không phải tra cứu danh sách và appendphương pháp của nó trên mỗi lần lặp. Tuy nhiên, việc hiểu danh sách vẫn thực hiện một vòng lặp cấp bytecode:

>>> dis.dis(<the code object for `[x for x in range(10)]`>)
 1           0 BUILD_LIST               0
             3 LOAD_FAST                0 (.0)
       >>    6 FOR_ITER                12 (to 21)
             9 STORE_FAST               1 (x)
            12 LOAD_FAST                1 (x)
            15 LIST_APPEND              2
            18 JUMP_ABSOLUTE            6
       >>   21 RETURN_VALUE

Sử dụng khả năng hiểu danh sách thay cho vòng lặp không tạo danh sách, tích lũy một cách vô nghĩa danh sách các giá trị vô nghĩa và sau đó vứt bỏ danh sách, thường chậm hơn vì tốn nhiều chi phí tạo và mở rộng danh sách. Việc hiểu danh sách không phải là phép thuật vốn nhanh hơn một vòng lặp cũ tốt.

Đối với các hàm xử lý danh sách chức năng: Mặc dù chúng được viết bằng C và có thể hoạt động tốt hơn các hàm tương đương được viết bằng Python, nhưng chúng không nhất thiết phải là lựa chọn nhanh nhất. Một số tốc độ được mong đợi nếu hàm cũng được viết bằng C. Nhưng hầu hết các trường hợp sử dụng một lambda(hoặc hàm Python khác), chi phí thiết lập liên tục các khung ngăn xếp Python, v.v. tiêu tốn bất kỳ khoản tiết kiệm nào. Đơn giản chỉ cần thực hiện cùng một công việc trong dòng, không cần gọi hàm (ví dụ: hiểu danh sách thay vì maphoặc filter) thường nhanh hơn một chút.

Giả sử rằng trong một trò chơi mà tôi đang phát triển, tôi cần vẽ các bản đồ phức tạp và khổng lồ bằng cách sử dụng các vòng lặp. Câu hỏi này chắc chắn sẽ có liên quan, ví dụ: nếu khả năng hiểu danh sách thực sự nhanh hơn, nó sẽ là một lựa chọn tốt hơn nhiều để tránh bị trễ (Mặc dù độ phức tạp trực quan của mã).

Rất có thể, nếu mã như thế này chưa đủ nhanh khi được viết bằng Python không được "tối ưu hóa" tốt, thì sẽ không có quá trình tối ưu hóa vi mô cấp độ Python nào làm cho nó đủ nhanh và bạn nên bắt đầu nghĩ đến việc giảm xuống C. Trong khi mở rộng. các tối ưu hóa vi mô thường có thể tăng tốc đáng kể mã Python, có một giới hạn thấp (về mặt tuyệt đối) cho điều này. Hơn nữa, ngay cả trước khi bạn đạt đến mức trần đó, việc cắn viên đạn và viết một số C. sẽ trở nên tiết kiệm chi phí hơn (tăng tốc 15% so với tăng tốc 300% với cùng một nỗ lực).

25
Anthony Kong 2014-03-01 14:44.

Nếu bạn kiểm tra thông tin trên python.org , bạn có thể thấy bản tóm tắt này:

Version Time (seconds)
Basic loop 3.47
Eliminate dots 2.45
Local variable & no dots 1.79
Using map function 0.54

Nhưng bạn thực sự nên đọc chi tiết bài viết trên để hiểu nguyên nhân của sự khác biệt về hiệu suất.

Tôi cũng khuyên bạn nên tính thời gian cho mã của mình bằng cách sử dụng timeit . Vào cuối ngày, có thể có một tình huống, ví dụ, bạn có thể cần thoát ra khỏi forvòng lặp khi một điều kiện được đáp ứng. Nó có thể nhanh hơn việc tìm ra kết quả bằng cách gọi điện map.

13
andreipmbcn 2014-03-01 14:56.

Bạn hỏi cụ thể về map(), filter()reduce(), nhưng tôi cho rằng bạn muốn biết về lập trình hàm nói chung. Sau khi tự mình kiểm tra điều này về vấn đề khoảng cách tính toán giữa tất cả các điểm trong một tập hợp điểm, lập trình chức năng (sử dụng starmapchức năng từ itertoolsmô-đun tích hợp) hóa ra hơi chậm hơn so với vòng lặp (mất 1,25 lần, trong thực tế). Đây là mã mẫu tôi đã sử dụng:

import itertools, time, math, random

class Point:
    def __init__(self,x,y):
        self.x, self.y = x, y

point_set = (Point(0, 0), Point(0, 1), Point(0, 2), Point(0, 3))
n_points = 100
pick_val = lambda : 10 * random.random() - 5
large_set = [Point(pick_val(), pick_val()) for _ in range(n_points)]
    # the distance function
f_dist = lambda x0, x1, y0, y1: math.sqrt((x0 - x1) ** 2 + (y0 - y1) ** 2)
    # go through each point, get its distance from all remaining points 
f_pos = lambda p1, p2: (p1.x, p2.x, p1.y, p2.y)

extract_dists = lambda x: itertools.starmap(f_dist, 
                          itertools.starmap(f_pos, 
                          itertools.combinations(x, 2)))

print('Distances:', list(extract_dists(point_set)))

t0_f = time.time()
list(extract_dists(large_set))
dt_f = time.time() - t0_f

Phiên bản chức năng có nhanh hơn phiên bản thủ tục không?

def extract_dists_procedural(pts):
    n_pts = len(pts)
    l = []    
    for k_p1 in range(n_pts - 1):
        for k_p2 in range(k_p1, n_pts):
            l.append((pts[k_p1].x - pts[k_p2].x) ** 2 +
                     (pts[k_p1].y - pts[k_p2].y) ** 2)
    return l

t0_p = time.time()
list(extract_dists_procedural(large_set)) 
    # using list() on the assumption that
    # it eats up as much time as in the functional version

dt_p = time.time() - t0_p

f_vs_p = dt_p / dt_f
if f_vs_p >= 1.0:
    print('Time benefit of functional progamming:', f_vs_p, 
          'times as fast for', n_points, 'points')
else:
    print('Time penalty of functional programming:', 1 / f_vs_p, 
          'times as slow for', n_points, 'points')
10
alphiii 2017-04-29 00:09.

Tôi đã viết một kịch bản đơn giản để kiểm tra tốc độ và đây là những gì tôi phát hiện ra. Trên thực tế, vòng lặp for là nhanh nhất trong trường hợp của tôi. Điều đó thực sự làm tôi ngạc nhiên, hãy kiểm tra dưới đây (đang tính tổng các bình phương).

from functools import reduce
import datetime


def time_it(func, numbers, *args):
    start_t = datetime.datetime.now()
    for i in range(numbers):
        func(args[0])
    print (datetime.datetime.now()-start_t)

def square_sum1(numbers):
    return reduce(lambda sum, next: sum+next**2, numbers, 0)


def square_sum2(numbers):
    a = 0
    for i in numbers:
        i = i**2
        a += i
    return a

def square_sum3(numbers):
    sqrt = lambda x: x**2
    return sum(map(sqrt, numbers))

def square_sum4(numbers):
    return(sum([int(i)**2 for i in numbers]))


time_it(square_sum1, 100000, [1, 2, 5, 3, 1, 2, 5, 3])
time_it(square_sum2, 100000, [1, 2, 5, 3, 1, 2, 5, 3])
time_it(square_sum3, 100000, [1, 2, 5, 3, 1, 2, 5, 3])
time_it(square_sum4, 100000, [1, 2, 5, 3, 1, 2, 5, 3])
0:00:00.302000 #Reduce
0:00:00.144000 #For loop
0:00:00.318000 #Map
0:00:00.390000 #List comprehension
7
tjysdsg 2020-02-17 15:41.

Tôi đã sửa đổi mã của @ Alisa và được sử dụng cProfileđể chỉ ra lý do tại sao việc hiểu danh sách nhanh hơn:

from functools import reduce
import datetime

def reduce_(numbers):
    return reduce(lambda sum, next: sum + next * next, numbers, 0)

def for_loop(numbers):
    a = []
    for i in numbers:
        a.append(i*2)
    a = sum(a)
    return a

def map_(numbers):
    sqrt = lambda x: x*x
    return sum(map(sqrt, numbers))

def list_comp(numbers):
    return(sum([i*i for i in numbers]))

funcs = [
        reduce_,
        for_loop,
        map_,
        list_comp
        ]

if __name__ == "__main__":
    # [1, 2, 5, 3, 1, 2, 5, 3]
    import cProfile
    for f in funcs:
        print('=' * 25)
        print("Profiling:", f.__name__)
        print('=' * 25)
        pr = cProfile.Profile()
        for i in range(10**6):
            pr.runcall(f, [1, 2, 5, 3, 1, 2, 5, 3])
        pr.create_stats()
        pr.print_stats()

Đây là kết quả:

=========================
Profiling: reduce_
=========================
         11000000 function calls in 1.501 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
  1000000    0.162    0.000    1.473    0.000 profiling.py:4(reduce_)
  8000000    0.461    0.000    0.461    0.000 profiling.py:5(<lambda>)
  1000000    0.850    0.000    1.311    0.000 {built-in method _functools.reduce}
  1000000    0.028    0.000    0.028    0.000 {method 'disable' of '_lsprof.Profiler' objects}


=========================
Profiling: for_loop
=========================
         11000000 function calls in 1.372 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
  1000000    0.879    0.000    1.344    0.000 profiling.py:7(for_loop)
  1000000    0.145    0.000    0.145    0.000 {built-in method builtins.sum}
  8000000    0.320    0.000    0.320    0.000 {method 'append' of 'list' objects}
  1000000    0.027    0.000    0.027    0.000 {method 'disable' of '_lsprof.Profiler' objects}


=========================
Profiling: map_
=========================
         11000000 function calls in 1.470 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
  1000000    0.264    0.000    1.442    0.000 profiling.py:14(map_)
  8000000    0.387    0.000    0.387    0.000 profiling.py:15(<lambda>)
  1000000    0.791    0.000    1.178    0.000 {built-in method builtins.sum}
  1000000    0.028    0.000    0.028    0.000 {method 'disable' of '_lsprof.Profiler' objects}


=========================
Profiling: list_comp
=========================
         4000000 function calls in 0.737 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
  1000000    0.318    0.000    0.709    0.000 profiling.py:18(list_comp)
  1000000    0.261    0.000    0.261    0.000 profiling.py:19(<listcomp>)
  1000000    0.131    0.000    0.131    0.000 {built-in method builtins.sum}
  1000000    0.027    0.000    0.027    0.000 {method 'disable' of '_lsprof.Profiler' objects}

IMHO:

  • reducemapnói chung là khá chậm. Không chỉ vậy, việc sử dụng sumtrên các trình vòng lặp được maptrả về chậm, so với việc nhập sumdanh sách
  • for_loop sử dụng append, tất nhiên là chậm ở một mức độ nào đó
  • khả năng hiểu danh sách không chỉ dành ít thời gian nhất để xây dựng danh sách, nó còn làm cho danh sách sumnhanh hơn nhiều, trái ngược vớimap
6
jjmerelo 2018-03-19 03:27.

Thêm một bước ngoặt cho câu trả lời Alphii , thực sự thì vòng lặp for sẽ tốt thứ hai và chậm hơn khoảng 6 lần so vớimap

from functools import reduce
import datetime


def time_it(func, numbers, *args):
    start_t = datetime.datetime.now()
    for i in range(numbers):
        func(args[0])
    print (datetime.datetime.now()-start_t)

def square_sum1(numbers):
    return reduce(lambda sum, next: sum+next**2, numbers, 0)


def square_sum2(numbers):
    a = 0
    for i in numbers:
        a += i**2
    return a

def square_sum3(numbers):
    a = 0
    map(lambda x: a+x**2, numbers)
    return a

def square_sum4(numbers):
    a = 0
    return [a+i**2 for i in numbers]

time_it(square_sum1, 100000, [1, 2, 5, 3, 1, 2, 5, 3])
time_it(square_sum2, 100000, [1, 2, 5, 3, 1, 2, 5, 3])
time_it(square_sum3, 100000, [1, 2, 5, 3, 1, 2, 5, 3])
time_it(square_sum4, 100000, [1, 2, 5, 3, 1, 2, 5, 3])

Những thay đổi chính là để loại bỏ các sumcuộc gọi chậm , cũng như có thể không cần thiết int()trong trường hợp cuối cùng. Đặt vòng lặp for và ánh xạ theo cùng một thuật ngữ khiến nó trở nên khá thực tế. Hãy nhớ rằng lambdas là khái niệm chức năng và về mặt lý thuyết không nên có tác dụng phụ, nhưng, tốt, chúng có thể có tác dụng phụ như thêm vào a. Kết quả trong trường hợp này với Python 3.6.1, Ubuntu 14.04, CPU Intel (R) Core (TM) i7-4770 @ 3,40GHz

0:00:00.257703 #Reduce
0:00:00.184898 #For loop
0:00:00.031718 #Map
0:00:00.212699 #List comprehension
4
Alisca Chen 2019-07-23 20:55.

Tôi đã quản lý để sửa đổi một số mã của @ alpiii và phát hiện ra rằng khả năng hiểu Danh sách nhanh hơn một chút so với vòng lặp for. Nó có thể là do int(), nó không công bằng giữa khả năng hiểu danh sách và vòng lặp for.

from functools import reduce
import datetime

def time_it(func, numbers, *args):
    start_t = datetime.datetime.now()
    for i in range(numbers):
        func(args[0])
    print (datetime.datetime.now()-start_t)

def square_sum1(numbers):
    return reduce(lambda sum, next: sum+next*next, numbers, 0)

def square_sum2(numbers):
    a = []
    for i in numbers:
        a.append(i*2)
    a = sum(a)
    return a

def square_sum3(numbers):
    sqrt = lambda x: x*x
    return sum(map(sqrt, numbers))

def square_sum4(numbers):
    return(sum([i*i for i in numbers]))

time_it(square_sum1, 100000, [1, 2, 5, 3, 1, 2, 5, 3])
time_it(square_sum2, 100000, [1, 2, 5, 3, 1, 2, 5, 3])
time_it(square_sum3, 100000, [1, 2, 5, 3, 1, 2, 5, 3])
time_it(square_sum4, 100000, [1, 2, 5, 3, 1, 2, 5, 3])
0:00:00.101122 #Reduce

0:00:00.089216 #For loop

0:00:00.101532 #Map

0:00:00.068916 #List comprehension

Related questions

MORE COOL STUFF

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett đã bất chấp những lời khuyên hẹn hò điển hình khi cô gặp chồng mình.

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Michael Sheen là một diễn viên phi lợi nhuận nhưng chính xác thì điều đó có nghĩa là gì?

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Ngôi sao của Hallmark Colin Egglesfield chia sẻ về những cuộc gặp gỡ với người hâm mộ ly kỳ tại RomaDrama Live! cộng với chương trình INSPIRE của anh ấy tại đại hội.

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Bạn sẽ phải phủi sạch đầu đĩa Blu-ray hoặc DVD để xem tại sao Northern Exposure trở thành một trong những chương trình nổi tiếng nhất của thập niên 90.

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

8 công dụng tuyệt vời của Baking Soda và Giấm

8 công dụng tuyệt vời của Baking Soda và Giấm

Bạn biết đấy, hai sản phẩm này là nguồn điện để làm sạch, riêng chúng. Nhưng cùng với nhau, chúng có một loạt công dụng hoàn toàn khác.

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Thủy điện rất cần thiết cho lưới điện của Hoa Kỳ, nhưng nó chỉ tạo ra năng lượng khi có nước di chuyển. Bao nhiêu nhà máy thủy điện có thể gặp nguy hiểm khi các hồ và sông cạn kiệt?

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Tóc tỉa từ các tiệm và các khoản quyên góp cá nhân có thể được tái sử dụng như những tấm thảm thấm dầu và giúp bảo vệ môi trường.

Đây là Tổng thống Trump đe dọa 'trợ cấp' xe điện của GM vì đóng cửa nhà máy

Đây là Tổng thống Trump đe dọa 'trợ cấp' xe điện của GM vì đóng cửa nhà máy

Trump và Giám đốc điều hành GM Mary Barra vào năm 2017. Kể từ khi tin tức nổ ra ngày hôm qua rằng General Motors đang cắt giảm việc làm ở Bắc Mỹ để chuẩn bị cho tương lai điện / xe tự hành / khủng khiếp có thể xảy ra của chúng tôi, gần như tất cả mọi người đã tự hỏi: Tổng thống Trump, người đã vận động tranh cử trên một nền tảng sẽ như thế nào của việc mang lại và duy trì việc làm ô tô của Mỹ, phải nói gì về điều này? Bây giờ chúng ta biết.

Bản vá lỗi tiếp theo của Fallout 76 sẽ mang lại một số bản sửa lỗi cần thiết

Bản vá lỗi tiếp theo của Fallout 76 sẽ mang lại một số bản sửa lỗi cần thiết

Bethesda cho biết ngày hôm nay trên Reddit, Fallout 76 sẽ có một bản vá lớn khác vào ngày 4 tháng 12, sẽ bắt đầu cố gắng khắc phục một số vấn đề lớn hơn của trò chơi. Ngoài ra, công ty cho biết họ có kế hoạch giao tiếp nhiều hơn trong tương lai về những gì nhóm Fallout 76 đang làm việc và khi nào các bản cập nhật mới cho trò chơi sẽ ra mắt.

Mạng lưới bệnh viện Công giáo sẽ không cho phép nhân viên phá thai tại phòng khám ngoài giờ làm việc

Mạng lưới bệnh viện Công giáo sẽ không cho phép nhân viên phá thai tại phòng khám ngoài giờ làm việc

Bạn có biết rằng một trong sáu bệnh nhân ở bệnh viện ở Hoa Kỳ được điều trị tại một cơ sở Công giáo? Và bạn có biết rằng quyền sở hữu của Công giáo hạn chế sâu sắc việc thiết lập các thủ tục y tế có thể được thực hiện trong các bệnh viện này, rõ ràng nhất là khi nói đến chăm sóc sức khỏe sinh sản? Bây giờ NPR báo cáo rằng sự gia tăng của các bệnh viện thuộc Công giáo đang gây khó khăn hơn cho các bác sĩ — những người bị cấm bởi các quy định do Hoa Kỳ viết.

Khói từ đám cháy rừng ở California đã đến tận thành phố New York

Khói từ đám cháy rừng ở California đã đến tận thành phố New York

Đường chân trời San Francisco bị che khuất bởi khói và khói mù do cháy rừng phía sau Đảo Alcatraz, Thứ Tư, ngày 14 tháng 11 năm 2018, ở San Francisco.

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Rothschild's luggage got lost, but luckily she has an incredible closet to shop: Sister Paris Hilton's!

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa. Từ Hollywood đến New York và mọi nơi ở giữa, hãy xem các ngôi sao yêu thích của bạn đang làm gì!

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

Các nhà điều tra đang xem xét liệu nhóm và nghi phạm có biết nhau trước vụ tấn công hay không

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Vụ kiện, nêu tên một số học khu, lập luận rằng dự luật "Không nói đồng tính" được ban hành gần đây của Florida "có hiệu quả im lặng và xóa bỏ học sinh và gia đình LGBTQ +"

Đường băng hạ cánh

Đường băng hạ cánh

Cuối hè đầu thu là mùa hoài niệm. Những chiếc đèn đường chiếu ánh sáng của chúng qua những con đường đẫm mưa, và những chiếc lá dưới chân - màu đỏ cam tắt trong bóng chạng vạng - là lời nhắc nhở về những ngày đã qua.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Vào năm 2021, tôi khuyến khích bạn suy nghĩ lại mọi thứ bạn biết về khách hàng mà bạn phục vụ và những câu chuyện bạn kể cho họ. Lùi lại.

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Vào ngày sinh nhật thứ 9 của Felix The Cat, tôi nhớ về một trong những mất mát lớn nhất trong cuộc đời trưởng thành của tôi - Sophie của tôi vào năm 2013. Tôi đã viết bài luận này và chia sẻ nó trên nền tảng này một thời gian ngắn vào năm 2013.

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Tôi ghét từ "tàu đắm". Mọi người cảm thấy thoải mái trong la bàn đạo đức của riêng mình, và khi làm như vậy, họ thấy mình vượt qua sự phán xét.

Language