У меня Андроид студия столько же жрет, и никаких расширений ставить не пришлось:) Если мы говорим про экономию памяти — однозначно vim. Или Geany, он память не жрет и довольно много из коробки умеет.
Color Highlight — показывает цвет цвета прямо в редакторе
EditorConfig — для поддержки одноименного формата
PlantUML — диаграммы прямо в редакторе
Script Commands — если лень писать свои плагины, можно цеплять абсолютно любые собственные скрипты к редактору
Главное, что нет необходимости ставить 3 IDE, если время от времени нужно править код на Java/JavaScript/ObjectiveC/C++.
Хотя и сам не прочь крутить подобные портянки, хочу предупредить читателей, этот код — не пример для подражания. Выход за границу 80 символов — сама по себе проблема, и если скрипт "причесать" до читаемого состояния, то в нём будет уже не 9, а без малого сотня строк. И гарантировать, что этот скрипт не развалится от случайно затесавшегося неформатного файлика, в отличие от настоящего парсера, невозможно. А когда он развалится, отладка превратится в ад (если этот факт вообще кто-то заметит).
Также для уменьшения времени работы, количества временных файлов да и просто вероятных ошибок, в Bash есть замечательная конструкция:
while read -r line; do
echo $((line**2))
done < <(seq 123)
В отличие от command | while ...do ... done она не создаёт новый сабшелл и позволяет избежать ошибок, связанных с потерей переменных.
чтение из разных конфигов, где я считываю значение переменных
Если позволяет формат конфигов — то не знаю ничего быстрее чем source config.cfg, всё что было внутри конфига превратится в переменные баша. Такой способ используется повсеместно в initscripts. Все эти ifcfg-eth0 в RHEL по крайней мере — по сути шелл-скрипты.
Ещё один способ, который годится для перегона нестандартного формата конфига — eval "$(sed ... config.ini)". Сед приводит конфиг в башеподобному виду, eval превращает в переменные.
Обычно так делают студенты домашку, так как им показали ограниченный набор базовых команд.
VAR1=$(cat file.cfg | grep var | cut -f2 | sed 's/"//')
… и так десять раз
#!/usr/bin/env bash
# prepare data
for A in {1..1000}; do
STRING+="Name$RANDOM Date$RANDOM Shell$RANDOM"$'\n'
done
echo "using cut"
time cut -d " " -f 3 <<<"$STRING" > /dev/null
echo "using shell"
time while read a b c; do
echo $c
done <<<"$STRING" > /dev/null
# using cut
# real 0.006
# у меня медленный компьютер, результат с echo аналогичен тому, что предлагает автор
# using shell
# real 0.026
Когда нужно обработать много данных — пайпы лучше.
Единичные случаи — да, эффективнее использовать bash-измы. Обратная совместимость пострадает, но мы вас предупреждали.
С другой стороны, измерять эти миллисекунды имеет смысл, только когда данных много, следовательно см. п. 1.
В последнее время cut работает хорошо. Не так давно в GNU coreutils cut работал так, что его обгонял awk.
Попробуйте memtest прогнать. Такой же «баг» ловили на Intel, тоже падал компилятор только на крупных проектах вроде ядра или gcc, оказалось — битая плашка памяти, заменили и всё прошло. Много потоков -> много памяти -> выше шанс словить битую ячейку.
В Shell другие правила экранирования спецсимволов, которые ls не учитывает. Более правильно экранирует printf %q. И всё же лучше не полагаться на это, а ls может оказаться без этих расширений (busybox). В идеале должно получиться вот так: $'troll\nfile'
Не сочтите за грубость, но это тоже не будет работать:)
touch 'troll'$'\n''file'
Навскидку, как это правильно можно было бы сделать в bash (на самом деле так делать не надо, но демонстрация проблем с экранированием символов в шелле исчерпывающая):
#!/bin/bash
FILES=()
SIZES=()
i=0
while read -rd $'\0' file; do
FILES+=("$file")
SIZES+=("$(wc -c < "$file") $i")
((i++))
done < <(find -mindepth 1 -maxdepth 1 -type f -print0)
for l in "${SIZES[@]}"; do
echo $l
done | sort -n | while read _ n; do
printf '%q\n' "${FILES[$n]}"
done
И всё ещё неправильно. В имени могут быть пробелы и даже переносы строк. Правильно — переписать всё на Си, что в ls и сделали.
Нет ничего удобнее, чем вбить ls -lrt и посмотреть последние изменения в каталоге. А ещё никто не мешает сделать удобные для запоминания алиасы: alias ListFilesSortedByLastModificationTime='ls -lrt'
На самом деле, даже такая мелочь как потребление памяти "хелловордом" в Python крайне раздражает. Python, который ещё ничего не делает, съедает сразу 6 МБ. Если мне надо запустить сотню скриптов параллельно — это уже проблема. Или другой пример — минималка CentOS, куча демонов — postfix, imap, https, systemd, rsyslog, у всех потребление памяти ~ 6-10 МБ. И выделяется firewalld, который по сути ничего не делает и жрёт при этом 25 МБ. Подозреваю, тут уже не в интерпретаторе дело, а в каких-нибудь хэш-таблицах, сделанных через односвязный список...
Но вот что интересно, если 100 человек отправит в апстрим аналогичный патч, снижающий потребление ОЗУ, то возможно сообщество прислушается?
В большинстве случаев можно и без макросов обойтись, вот например шаблон, который ведёт себя также как и функция print в Питоне:
template print*(x: varargs[string, `$`], file: File = stdout) =
var res = ""
for i in x:
addSep(res, " ")
if i != nil:
res.add(i)
else:
res.add("(nil)")
file.writeLine(res)
или withFile, который сам закрывает дескриптор после выхода из блока:
А они и взяли pcre, но я никогда ещё такого медленного pcre не видел:
# 4.5 sec
import re
let exp = re"agggtaaa|tttaccct"
var c = 0
for line in "in.txt".lines:
if line.find(exp) != -1:
c += 1
echo (c)
# 2 sec
import pegs
let exp = peg"'agggtaaa'/'tttaccct'"
var c = 0
for line in "in.txt".lines:
if line.find(exp) != -1:
c += 1
echo (c)
Можно, это будет просто template. Макросы вообще позволяют манипулировать синтаксическим деревом, т. е. они не для простого оборачивания кода, а для магии. Макорс может полностью изменить переданный ему на вход кусок кода.
Переписывал на Nim пару скриптов-парсеров (~1000 LOC) для собственных нужд с целью поднять производительность того же самого, написанного на Питоне. Привлекает анонсированные аналогичный синтаксис и сравнимая с C скорость, по факту — так и есть. Скорость разработки немного медленнее, так как до сих пор некоторых фишек не хватает, но благодаря макросам ему можно простить такие косяки.
Что понравилось:
классы, объекты — всё это практически имеет нулевой оверхэд
сборка мусора работает довольно быстро
такой извращённой (в хорошем смысле) системы шаблонов и макросов я нигде не встречал
сборка через трансляцию в С, всегда можно его потюнить до производительности, сравнимой с C. К тому же можно распространять исходники в виде, оттранслированном в C — обфускация кода из коробки с неплохой переносимостью
хорош для разбора всевозможных xml/json и прочих разношёрстных конфигов с целью генерации отчётов
сравнительно безопасен, отстрелить ногу можно, но примерно с той же вероятностью, что и в питоне — по незнанию особенностей языка
легко подцепить функцию/библиотеку из C, если чего-то не хватает
очень легко собирается и самодостаточен, в плане переносимости лучшего варианта не сыскать
оптимизирующие шаблоны — отдельная песня. Можно целые куски кода, вроде "разделить строку по пробелам, взять подстроку длиной 10 символов от первого элемента" по мере необходимости переписывать на более оптимальные, с меньшей нагрузкой на сборщик мусора, при этом читаемость кода никак не пострадает. Эти шаблоны прячутся где-нибудь и ждут подходящего паттерна.
Что не понравилось:
баги — проклятье данного проекта. Их уже более 700, количество растёт, сообщество не успевает их фиксить.
удручающие решения в стандартной библиотеке. Ещё недавно чтение файлов работало посимвольно, через fgetc. Потоки (streams) — до сих пор небуферизованные, работают посимвольно и не спеша.
печальное состояние поддержки юникода и вообще какой-либо работы с языками, отличными от английского, отдельного упоминания достойна полная отсутствия поддержки переводов (по типу gettext)
биндинги к библиотекам сделаны на коленке любителями (см. GTK)
его пилит полтора человека, и ситуация не спешит меняться
регулярки прикручены наспех и работают медленнее, чем perl в десятки раз. Редкий язык, где реализация "в лоб" быстрее regexp.
отсутствует возможность использования рантайма, чтобы бинарники не пухли. Всё компилируется статически
сомнительная реализация исключений через longjump
из-за сборщика мусора нетривиально на нём разрабатывать библиотеки и модули к другим программам — требуется обязательное выполнение NimMain где-нибудь
коллеги смотрят на вас как на ненормального
Несмотря на недостатки, хороший язык "для себя" и можно на нём переписать что-то, что раньше было написано на Баше или Питоне, где нужна скорость. Продакшн даже не пробуйте — где вы потом программиста на Nim искать будете?:)
P.S. Подписываюсь на эссе по Nim от автора. Crystal пробовал — осталось впечатление, что он ещё более сырой, чем Nim.
У меня Андроид студия столько же жрет, и никаких расширений ставить не пришлось:) Если мы говорим про экономию памяти — однозначно vim. Или Geany, он память не жрет и довольно много из коробки умеет.
Добавлю ещё отличные плагины:
Главное, что нет необходимости ставить 3 IDE, если время от времени нужно править код на Java/JavaScript/ObjectiveC/C++.
Хотя и сам не прочь крутить подобные портянки, хочу предупредить читателей, этот код — не пример для подражания. Выход за границу 80 символов — сама по себе проблема, и если скрипт "причесать" до читаемого состояния, то в нём будет уже не 9, а без малого сотня строк. И гарантировать, что этот скрипт не развалится от случайно затесавшегося неформатного файлика, в отличие от настоящего парсера, невозможно. А когда он развалится, отладка превратится в ад (если этот факт вообще кто-то заметит).
Также для уменьшения времени работы, количества временных файлов да и просто вероятных ошибок, в Bash есть замечательная конструкция:
В отличие от
command | while ...do ... done
она не создаёт новый сабшелл и позволяет избежать ошибок, связанных с потерей переменных.Если позволяет формат конфигов — то не знаю ничего быстрее чем
source config.cfg
, всё что было внутри конфига превратится в переменные баша. Такой способ используется повсеместно в initscripts. Все эти ifcfg-eth0 в RHEL по крайней мере — по сути шелл-скрипты.Ещё один способ, который годится для перегона нестандартного формата конфига —
eval "$(sed ... config.ini)"
. Сед приводит конфиг в башеподобному виду, eval превращает в переменные.Обычно так делают студенты домашку, так как им показали ограниченный набор базовых команд.
VAR1=$(cat file.cfg | grep var | cut -f2 | sed 's/"//')
… и так десять раз
Дело в подготовке данных (вы вызываете cut 1000 раз, а я один раз но для 1000 строк).
Если не можете выиграть битву, поменяйте поле:
В последнее время cut работает хорошо. Не так давно в GNU coreutils cut работал так, что его обгонял awk.
Подарите джуниорам бесценные часы отладки:) Можно добавить более весёлую шутку на свой вкус.
И это вы ещё поверхность не поцарапали...
Спойлер: представим, что $dir не существует или пустой.
Тысячи их.
А ещё
bash -ue script.sh
.В целом хорошо, что появляются обучающие статьи про баш, плохо то, что учат они не тому. И не учат делать отступы в скриптах.
P.S.
P.P.S. В systemd поняли ошибку и переписали всё с шелл-портянок на Си. Но в последний момент всё равно что-то пошло не так...
У меня такая же есть на 32 Кб, всё думаю, может и правда сделать заметку "во что превратился мой .bashrc"?:)
лишний раз subshell не будет запускаться (вдруг и правда кому-то нужно)
тоже хотел узнать, что может быть проще ab, к тому же предлагаемый вариант ужасен — wget намусорит файлами вида index.html.*
И если уж на то пошло, сильно укоротить можно:
seq 1000 | xargs -I{} -P20 wget -qO/dev/null ya.ru
(да простит нас Яндекс)В Shell другие правила экранирования спецсимволов, которые ls не учитывает. Более правильно экранирует
printf %q
. И всё же лучше не полагаться на это, а ls может оказаться без этих расширений (busybox). В идеале должно получиться вот так:$'troll\nfile'
Не сочтите за грубость, но это тоже не будет работать:)
Навскидку, как это правильно можно было бы сделать в bash (на самом деле так делать не надо, но демонстрация проблем с экранированием символов в шелле исчерпывающая):
Это из коллекции "1000 и один способ выстрелить себе в ногу в Shell". Если вы всё ещё полагаетесь в скриптах на вывод команды ls, настоятельно рекомендуется к прочтению, и это тоже.
У некоторых людей такой юниксвейный подход к проектированию интерфейсов вызывает глубокую депрессию.
И всё ещё неправильно. В имени могут быть пробелы и даже переносы строк. Правильно — переписать всё на Си, что в ls и сделали.
Нет ничего удобнее, чем вбить
ls -lrt
и посмотреть последние изменения в каталоге. А ещё никто не мешает сделать удобные для запоминания алиасы:alias ListFilesSortedByLastModificationTime='ls -lrt'
На самом деле, даже такая мелочь как потребление памяти "хелловордом" в Python крайне раздражает. Python, который ещё ничего не делает, съедает сразу 6 МБ. Если мне надо запустить сотню скриптов параллельно — это уже проблема. Или другой пример — минималка CentOS, куча демонов — postfix, imap, https, systemd, rsyslog, у всех потребление памяти ~ 6-10 МБ. И выделяется firewalld, который по сути ничего не делает и жрёт при этом 25 МБ. Подозреваю, тут уже не в интерпретаторе дело, а в каких-нибудь хэш-таблицах, сделанных через односвязный список...
Но вот что интересно, если 100 человек отправит в апстрим аналогичный патч, снижающий потребление ОЗУ, то возможно сообщество прислушается?
В большинстве случаев можно и без макросов обойтись, вот например шаблон, который ведёт себя также как и функция print в Питоне:
или withFile, который сам закрывает дескриптор после выхода из блока:
В результате Nim становится не намного многословнее баша.
А они и взяли pcre, но я никогда ещё такого медленного pcre не видел:
Можно, это будет просто template. Макросы вообще позволяют манипулировать синтаксическим деревом, т. е. они не для простого оборачивания кода, а для магии. Макорс может полностью изменить переданный ему на вход кусок кода.
Переписывал на Nim пару скриптов-парсеров (~1000 LOC) для собственных нужд с целью поднять производительность того же самого, написанного на Питоне. Привлекает анонсированные аналогичный синтаксис и сравнимая с C скорость, по факту — так и есть. Скорость разработки немного медленнее, так как до сих пор некоторых фишек не хватает, но благодаря макросам ему можно простить такие косяки.
Что понравилось:
Что не понравилось:
Несмотря на недостатки, хороший язык "для себя" и можно на нём переписать что-то, что раньше было написано на Баше или Питоне, где нужна скорость. Продакшн даже не пробуйте — где вы потом программиста на Nim искать будете?:)
P.S. Подписываюсь на эссе по Nim от автора. Crystal пробовал — осталось впечатление, что он ещё более сырой, чем Nim.