kb 24.08.2011 17:31 Gajim

Новости с фронта "asd" += "dsa". Как известно, в CPython += быстрый, а в PyPy — медленный. Объясняется это тем, что в CPython сделан некоторый хак для ускорения (в будущем, возможно, что-то появится и в PyPy). Но суть в том, что "собирать" строку через += в питоне в принципе неправильно, потому что каждый += создает новую строку. (по иронии, хак в CPython запилил один из разработчиков PyPy).

Таким образом, собирайте вашу строку при помощи u"".join([список_строк]) и не выпендривайтесь. Ну я лично еще сделал некоторый класс UnicodeBucket, но наверное проще не выпендриваться и таки u"".join() использывать

1. werehuman 24.08.2011 17:32 Psi+

это ты выпендриваешься, а не мы. += это просто, понятно и быстро

2. kbwerehuman /1 24.08.2011 17:34 Gajim

это ты не выпендривайся. += даже в CPython тормознутое говно

3. werehumankb /2 24.08.2011 17:34 Psi+

ну так естественно, по сравнению с StringIO да. А через join — это пиздец

4. kbwerehuman /3 24.08.2011 17:35 Gajim

почему?

5. werehumankb /4 24.08.2011 17:37 Psi+

потому что ты создаёшь ещё один список и выглядит это как последнее говно.

6. kbwerehuman /3 24.08.2011 17:37 Gajim

как раз через join() — правильный способ. Потому что ты, по сути, собираешь строку из кусков. То есть у тебя список кусков и тебе их надо склеить. Семантически join() — верный способ. А cStringIO — это file-like объект. Создавать file-like объект для сборки строки — семантически неверно нихуя.

7. kbwerehuman /3 24.08.2011 17:38 Gajim

ret_val = ["initial value"], ret_val.append("moar moar moar"), u"".join(ret_val). Нормально выглядит. Уж в сравнении с cStringIO так точно.

8. werehumankb /7 24.08.2011 17:41 Psi+

или ret_val = "initial value", ret_val += "moar moar moar". Сравни

9. kbwerehuman /8 24.08.2011 17:42 Gajim

ну вот для таких как ты я и написал UnicodeBucket. На скриншот глянь. Будет ret_val = UnicodeBucket("initial value"), ret_val += "moar moar moar". Э?

10. werehumankb /9 24.08.2011 17:43 Psi+

а как потом получаешь строку из ret_val?

11. kbwerehuman /8 24.08.2011 17:43 Gajim

сама получится когда unicode() над ней делать будут (или печатать или что там)

12. kbwerehuman /8 24.08.2011 17:43 Gajim

короче лениво будет сидеть и ждать, пока не потребуют преобразования в строку

13. werehumankb /11 24.08.2011 17:43 Psi+

не нужно ибо совсем не очевидно, хотя оптимизирует ровно одну строку

14. kbwerehuman /13 24.08.2011 17:44 Gajim

щито? что тебе не очевидно? Почему одну строку?

15. werehumankb /14 24.08.2011 17:45 Psi+

не очевидно будет тому человеку, который откроет твой код, добредёт до огромного цикла, увидит, что ты к строке прибавляешь строку и воткнёт что-нибудь рядом для этой строки. А оно херню сделает — выдаст какой-то UnicodeBucket и давай ищи, что это и откуда

16. kbwerehuman /15 24.08.2011 17:46 Gajim

какую херню сделает? Что воткнет?

17. werehumankb /16 24.08.2011 17:46 Psi+

да что угодно. Не вижу смысла плодить абстракции ради экономии одной строчки.

18. kbwerehuman /17 24.08.2011 17:47 Gajim

да какая нахрен одна строчка? Ты не видишь, что оно медленнее в 200 раз??

19. werehumankb /18 24.08.2011 17:48 Psi+

ты сделал абстракцию над [] + join. Всего-то

20. kbwerehuman /17 24.08.2011 17:48 Gajim

и это только на 30000

21. kbwerehuman /19 24.08.2011 17:49 Gajim

нет. Я сделал абстракцию над "собиранием строки" для возврата, это очень частая операция много где. А реализация может быть через [] + join, может через cStringIO. Но правильнее через [] + join, да.

22. kbwerehuman /19 24.08.2011 17:50 Gajim

так вот я и пришел к тому, что буду использовать [] + join на прямую, но для тех, кто считает "фууу, некрасиво" напиал UnicodeBucket (точнее, для себя писал, а потом понял, что мне не лень [] + join делать)

23. werehumankb /21 24.08.2011 17:50 Psi+

и зачем тебе разные реализации?

24. kbwerehuman /23 24.08.2011 17:50 Gajim

не понял, какие разные реализации?

25. werehumankb /22 24.08.2011 17:50 Psi+

никому не лень, если оно действительно надо

26. werehumankb /24 24.08.2011 17:50 Psi+

на join и на stringio

27. kbwerehuman /26 24.08.2011 17:51 Gajim

незачем. Ты просто сказал, что абстракция над [] + join. А я говорю, что это абстракция над совершенно другим.

28. kbwerehuman /26 24.08.2011 17:51 Gajim

а [] является лишь реализацией этой абстракции, и возможна и другая реализация, через cStringIO, но абстракция все равно той же останется

29. kbwerehuman /26 24.08.2011 17:52 Gajim

просто нельзя говорить "это абстракция над тем-то и тем-то", рассказывая реализацию этой абстракции. Абстракция для того и нужна, чтобы объяснять что она делает, а не как.

30. werehumankb /29 24.08.2011 17:53 Psi+

я не собираюсь пользоваться непонятно чем, мне нужно знать, что внутри твоей абстракции. И, как выяснилось, это просто обёртка над методами

31. kbwerehuman /30 24.08.2011 17:53 Gajim

А ЧЕМ ЭТО ЕЩЕ МОЖЕТ БЫТЬ? В программировании всё — просто обертка над методами.

32. werehumankb /31 24.08.2011 17:54 Psi+

неправда. Бывают не просто обёртки над методами, а обёртки, делающие что-то новое.

33. kbwerehuman /32 24.08.2011 17:55 Gajim

например?

34. werehumankb /33 24.08.2011 17:55 Psi+

например += не содержит одну строчку "self.lst.append", а __str__ не содержит одну строчку "return ''.join(self.lst)". А содержит две или три строчки.

35. kbwerehuman /34 24.08.2011 17:56 Gajim

Тебе расписать на две или три строчки или что?

36. werehumankb /35 24.08.2011 17:57 Psi+

зачем расписывать на три строчки то, что прекрасно и без препятствий влазит в одну? Просто незачем плодить лишние сущности, которые только путают всех, кто читает твой код

38. kbwerehuman /36 24.08.2011 17:59 Gajim

пойми. Есть проблема: нельзя пользоваться += для сборки строки из большого количества кусков. Точка. Нельзя и всё, потому что тормоз, потому что на каждый += создается новая строка. Надо построить некоторую абстракцию для "сборки строки в одну". Вот я её и написал. Хочешь — пиши [] + join, хочешь — используй эту абстракцию. И там и там ты будешь прав. Но во втором случае только потому, что абстракция не присутствует в стандартном питоне и накладно её городить каждый раз.

39. utros 24.08.2011 17:59 Adium

man stringbuilder

40. kbutros /39 24.08.2011 18:00 Gajim

в точку

41. werehumankb /38 24.08.2011 18:00 Psi+

вот и буду использовать [] + join, чтобы не было лишних вызовов

42. kbwerehuman /41 24.08.2011 18:00 Gajim

может сразу на ассамблере будешь писать?

43. werehumankb /42 24.08.2011 18:01 Psi+

нет, не буду. Буду использовать абстракции только там, где они нужны

44. utroskb /42 24.08.2011 18:01 Adium

Нужно паять программы из транзисторов и конденсаторов, а остальное — понты и не нужно.

45. werehuman 24.08.2011 18:02 Psi+

кстати, оказывается твой класс уже давно существует. from UserString import MutableString

46. kbwerehuman /43 24.08.2011 18:03 Gajim

по поводу однострочных абстракций — вот тебе хороший пример http://habrahabr.ru/blogs/cpp/126227/

47. rtsomekb /6 24.08.2011 18:03

зато pythonic

48. werehumankb /46 24.08.2011 18:04 Psi+

как видишь, их абстракции состоят не из одной строчки, а из многих

49. kbutros /44 24.08.2011 18:04 Gajim

нужно строить последовательности из расколотых дров, заставлять их двигаться при помощи силы ручья и ветра

50. rtsomekb /38 24.08.2011 18:05

в жабе эту хуйню больше пяти лет назад заоптимизировали, заметьте, что питон старше жабы.

51. utroswerehuman /32 24.08.2011 18:05 Adium

Обёртки делающие что-то новое — обёртки над обёртками.

52. kbrtsome /50 24.08.2011 18:05 Gajim

да жаба вообще молодцы, и денег больше зарабатывают

53. werehumanrtsome /50 24.08.2011 18:05 Psi+

в питоне тоже заоптимизировали. Просто ОП использует маргинальные интерпретаторы

54. kbwerehuman /53 24.08.2011 18:06 Gajim

недозаоптимизировали. Все равно тормоз же (в 200 раз!)

55. rtsomekb /52 24.08.2011 18:08 tzeench

чувствую — где-то подьёбка, а где — понять не могу...

56. kbrtsome /55 24.08.2011 18:09 Gajim

:-)

57. kbwerehuman /45 24.08.2011 18:09 Gajim

его задепрекейтили в python 3

58. werehumankb /57 24.08.2011 18:09 Psi+

а почему?

60. werehumankb /59 24.08.2011 18:11 Psi+

о, так тем более. bytearray намного лучше, не надо лишних импортов делать

61. kbwerehuman /60 24.08.2011 18:12 Gajim

ага, всего-то encode-decode все время хуячить в bytearray. Нет спасибо.

62. kbwerehuman /60 24.08.2011 18:13 Gajim

There are no mutable unicode strings, because this is considered an uncommon application, but you can always implement __unicode__ (or __str__ for Python 3) and encode methods on your custom sequence type to emulate one.

63. kbwerehuman /60 24.08.2011 18:13 Gajim

предлагает написать свой UnicodeBucket, прикинь

64. werehumankb /63 24.08.2011 18:14 Psi+

уфф. Пусть будет так

65. kbwerehuman /64 24.08.2011 18:14 Gajim

нет, ну я все равно пойду использовать [] + join, потому что накладно и лень его импортировать везде, но тем, кто UnicodeBucket будет использовать по яйцам стучать не стану

66. kbwerehuman /64 24.08.2011 18:15 Gajim

такой себе "исторический хак"

67. kbkb /66 24.08.2011 18:17 Gajim

нет, передумал, назову его StringBuilder и буду использовать, всё же так правильней, и его можно документировать (четко написать зачем он нужен, в отличии от [] + join). А еще в нём кеширование есть, так что просчитываться будет один раз только.

68. werehumankb /67 24.08.2011 18:18 Psi+

не забудь очистку кеша на +=

69. kbwerehuman /68 24.08.2011 18:18 Gajim

вроде не забыл, ага

Do you really want to delete ?